2

In Java I understand class fields as variables that are accessible from the whole everywhere in the class and that kind of describe the state-structure of instances. In Java field are defined outside any method (and this is the only thing that can be outside of methods).

In Scala "outside any method" is the main constructor - in other words: there is no "outside any method". Thus fields are defined in the main constructor. Thus any variable/value in the constructor is a field. Even arguments given to the constructor are automatically class fields and not local constructor variables as in Java.

In case I got all that right: Are there local variables/values in Scala constructors?

If not: Why was it decided that such a thing is not needed?

Clarficiation: I ask about concepts, not a specific case. Also I do not ask about how to work around to get something like local variables (although I would appreciate it if the answer were that there aren't any).

Make42
  • 12,236
  • 24
  • 79
  • 155
  • 2
    Possible duplicate of [Constructor-local variables in Scala](http://stackoverflow.com/questions/10162539/constructor-local-variables-in-scala) – Aleksandar Stojadinovic Oct 04 '16 at 14:42
  • @AleksandarStojadinovic: Have you read the other question? As far as I understand that is a specific case and my question is about concepts. – Make42 Oct 04 '16 at 14:51
  • I thought your question was "are there such variables", and the answer from the other question is:"No". Or am I missing something? – Aleksandar Stojadinovic Oct 04 '16 at 15:02
  • @AleksandarStojadinovic: Where do you read in the other question's answers that there is no such Thing as local variables for constructors? Also: Why was it decided that such a thing is not needed? – Make42 Oct 04 '16 at 15:07

1 Answers1

2

The entire class body is "the contructor".

You can always restrict the scope of any variable to be a small as you like with a pair of braces, so there is no reason to introduce an additional "concept", that serves no specific purpose. Occam's razor.

  class Foo(bar: String) { // constructor parameter
    val baz = "baz";  // class member
    {
      val bat = "bat" // "local" variable
      println(bar + baz + bat) // all three are visible
    }
    println(bar + baz) // only first two are accessble
  }
  println (new Foo("bar").baz) // only class member can be accessed here
Dima
  • 39,570
  • 6
  • 44
  • 70
  • But local variables exist in auxiliary constructors, right? Is it simply that the syntax makes them possible or is there are reason why there should be local variables? – Make42 Oct 05 '16 at 09:22
  • @Make42 "local variable" exist anywhere between a pair of braces. If you write an auxiliary constructor like this `def this() = foo` it can't have local variables. If you write it like this `def this() = { val foo = 1; bar() }` then it can. It's not about the type of constructor, it's about the braces. Put them in the main constructor - you can have local variables too. Don't put them in - you can't. – Dima Oct 05 '16 at 10:24
  • Actually, an auxiliary constructor always has to be of the form `def this(...) = { this(...); ... }`. You can however write `def this() = this({val foo = 1; foo})`. – Jasper-M Oct 05 '16 at 12:02
  • @Jasper-M how about `def this() = this("foo", "bar", "baz")` ? ;) – Dima Oct 05 '16 at 13:45
  • @Dima You can fill in those dots with whatever you like :p – Jasper-M Oct 05 '16 at 13:51
  • @Jasper-M I meant that it is possible to have a constructor without braces around the body. – Dima Oct 05 '16 at 17:10
  • The last line puzzles me: If `bar` is a class member (here `public val`), shouldn't it also be accessible from the last line of the code in your answer? Yet you write "only class member can be accessed here". Or did you mean "only class member**s** can be accessed here"? – Make42 Oct 05 '16 at 18:43
  • @Make42 bar isn't a class member, it's just a constructor's parameter. If `Foo` was a `case class`, then it would make all its parameters members. Regular classes don't do that, but you can require that explicitly if you want to: `class Foo(val bar: String)` - here `bar` would be a member. – Dima Oct 05 '16 at 21:16
  • This does not restrict to case classes, but is also true for normal classes: http://joelabrahamsson.com/learning-scala-part-four-classes-and-constructors/#constructors-in-scala - or am I wrong? – Make42 Oct 06 '16 at 20:00
  • @Make42 yes, you are wrong. And so is the author of the page you referenced. – Dima Oct 06 '16 at 20:14