Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why it is not possible to override mutable variable in scala?

Why it is not possible to override mutable variable in scala ?

class Abs(var name: String){
}

class AbsImpl(override var name: String) extends Abs(name){
}

Above code gives following compile time error :-

variable name cannot override a mutable variable

If name is declared val, then above code works fine.

like image 741
mogli Avatar asked Jul 14 '15 05:07

mogli


People also ask

How do you override a variable in Scala?

In scala, you can override only those variables which are declared by using val keyword in both classes.

Can Val be overridden?

override var description:String =”It is a square.” It is the same example as above but here errors are found as here, var is used in the sub-classes to override the fields which is not possible as val cannot be overridden by the var as stated above.

Is variable mutable in Scala?

By contrast, Scala has two types of variables: val creates an immutable variable (like final in Java) var creates a mutable variable.


2 Answers

The short answer: you need to pass -Yoverride-vars to the Scala compiler.

According to the spec, a var is both a getter and a setter, and normal overriding rules apply for these methods. However, this proved to have some unwanted consequences w.r.t. to the final keyword and inlining. The code in the compiler mentions some spec clarifications would be needed:

// TODO: this is not covered by the spec. We need to resolve this either by changing the spec or removing the test here.
if (!settings.overrideVars)
  overrideError("cannot override a mutable variable")

A related ticket: SI-3770

like image 56
Iulian Dragos Avatar answered Oct 07 '22 20:10

Iulian Dragos


If you could override a var with a var, then the overriding member could have a narrower type. (That's how overriding is defined.)

You could then assign a value of a wider type and then read it expecting the narrower type, and fail.

Illustration of the setter involved:

scala> class A ; class B extends A
defined class A
defined class B

scala> abstract class C { var x: A } ; class D extends C { var x: B = _ }
<console>:13: error: class D needs to be abstract, since variable x in class C of type A is not defined
(Note that an abstract var requires a setter in addition to the getter)
       abstract class C { var x: A } ; class D extends C { var x: B = _ }
                                             ^

scala> abstract class C { var x: A }
defined class C

scala> class D extends C { var x: B = _ ; def x_=(a: A) = ??? }
defined class D
like image 31
som-snytt Avatar answered Oct 07 '22 21:10

som-snytt