Why does Scala language require you initialize a instance variable instead of relying on a default value?

20,560

Solution 1

You can apply the annotation when you specify it as a constructor argument. Also, you may need to use a meta-annotation to restrict which target the annotation you're using is applied to - see http://www.scala-lang.org/api/2.10.2-RC2/index.html#scala.annotation.meta.package

Your question about "relying on a default value" is somewhat unclear, though. Initialization using an underscore corresponds to assigning the value of the variable to null. What other default are you thinking of?

Solution 2

If you use code like the following you are declaring, that the name should be abstract:

class A {
  var name: String
}

I suppose you already knew that. So your question is rather of the syntactical nature. The answer is consistency with other possible abstract candidates.

Suppose you want to do something like this:

class A {
   var variable: String = _ // variable has some default value (probably null)
   val value: String = _ // value cannot have any default values, since it cannot be reassigned later.
   def method: String = _ // method could return some default value (probably null)
   type theType = _ // what should the default type be? (Any perhaps?)
}

The last three examples don't even compile. Now suppose you want to do something like this:

class A {
   var variable: String
   val value: String
   def method: String
   type theType
}

From my point of view, even someone who barely understands Scala sees only declarations. There is no way to misinterpret them, because there is nothing there else than declarations. The one and only confusion arises when you come from another language and assume for a second that there are some default values. But this confusion is gone as soon as you see the first example (the one with the default values). And btw your class has to be a part of an abstract hierarchy in order to be allowed to declare abstract members, so even if you are new to the language you already get some extra help from the compiler.

I hope this answers your question and happy coding.

Solution 3

Scala has no issue with "var name: String" in the class body. Did you try it? It doesn't mean what you want it to mean, though. It's an abstract var.

abstract class A {
  var name: String
}
// some possible uses for abstract vars
trait B { type T ; var name: T }
class B1 extends B { type T = Int ; var name: Int = 5 }
// hey, no storage
class B2 extends B { type T = String ; def name = "abc" ; def name_=(x: String) = () }
Share:
20,560

Related videos on Youtube

Arthur Ronald
Author by

Arthur Ronald

IT analyst Feel free to contact me at arthurseveral [at] gmail [dot] com

Updated on July 17, 2020

Comments

  • Arthur Ronald
    Arthur Ronald over 3 years

    Scala language requires you initialize your instance variable before using it. However, Scala does not provide a default value for your variable. Instead, you have to set up its value manually by using the wildcard underscore, which acts like a default value, as follows

    var name:String = _
    

    I know, i know... I can define a constructor in the class definition, which takes as parameter our instance variable, so Scala does not force its initialization as shown below

    class Person(var name:String) 
    

    However, i need to declare it in the body because i need to use a Java annotation whose ElementType is FIELD or METHOD; that is, it can just be applied to either a instance variable or method declared in the body of our class.

    Question: Why does Scala language require you initialize a instance variable - be it a default value _ or whatever you want - declared in the body of a class instead of relying on a default value ?

    • Admin
      Admin over 12 years
      Martin's preference would be my guess :-) At the very least it's explicit and the extra 2 characters (4 with spaces) aren't terribly daunting. It sort of seems silly that Java (a very verbose language) lets the assignment be omitted. Also, it seems misleading to say the "constructor arguments" (dunno what they are really called :-/) aren't forced to be initialized -- they most certainly are when the object is instantiated.
  • Arthur Ronald
    Arthur Ronald over 12 years
    I know underscore sign is used to assign a default value. However, i want to know why Scala does not allow something like var name:String (without underscore assignment) instead when declared in the class body. You pointed out a nice feature of Scala (+1) which i did not know. However, it not fulfill my needs because i also need a no-arg constructor which is overridden if i declare my instance variables in a constructor declared in the class definition
  • Arthur Ronald
    Arthur Ronald over 12 years
    If i just declare var name:String; when compiled into a .class file, Scala compiler will complain: variable name is not defined. So i would like to know, even because of design issues, why Scala does not allow to use var name:String in the class body without declaring its initial value; be it a default value or whatever
  • Kris Nuttycombe
    Kris Nuttycombe over 12 years
    The reason that the assignment is required is, I believe, so that the compiler can distinguish between an abstract var (which is compiled to a pair of abstract methods) and a concrete var, which also requires the field to be generated in the class file.
  • Arthur Ronald
    Arthur Ronald over 12 years
    Thank you for your answer (+1)
  • psp
    psp over 12 years
    You could re-read my answer, which you seem to have ignored. Are you asking why "abstract" exists? An unimplemented abstract member means you cannot instantiate the class. This is by design, just like in java.