Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scala assigning vals

Tags:

Why isn't it possible to have this:

def main(args:Array[String]) {     val whatever:String // Have it uninitialized here      if(someCondition) {         whatever = "final value" // Initialize it here     } } 

I don't understand why this shouldn't be legal. I know that I can make it a var, but why do we have to initialize the val exactly when we declare it? Doesn't it seem more logical to be able to initialize it later?

like image 804
Geo Avatar asked Oct 26 '10 18:10

Geo


People also ask

How do I assign a value to Val in Scala?

If for some reason you cannot change a val to a var and still need to change its value, you can do this using reflection. This works, but it is evil. Since Scala runs on the JVM, there's no way to prevent this sort of mischief, but it goes against the fundamental design of the language. Any usage of field.

How do you define Val in Scala?

In the above syntax, the variable can be defined in one of two ways by using either the 'var' or 'val' keyword. It consists of 'variable_name' as your new variable, followed by a colon. The data type of variable is 'variable_datatype. ' which can be any valid data type.

Is it OK to use VAR in Scala?

Even from a functional programming point of view, you can use vars (or mutable objects) locally, if they don't leave the scope where they are defined.

What is lazy Val in Scala?

Scala provides a nice language feature called lazy val that defers the initialization of a variable. The lazy initialization pattern is common in Java programs. Though it seems tempting, the concrete implementation of lazy val has some subtle issues.


2 Answers

You can do:

  val whatever =     if (someCondition)       "final value"     else       "other value" 
like image 156
Nicolas Payette Avatar answered Sep 21 '22 02:09

Nicolas Payette


The Java solution is actually a workaround to the problem that not all expressions return values, so you can't write this in Java:

final String whatever = if (someCondition) {     "final value" } else {     "other value" } 

Increasingly, the trend in Java is to use the ternary operator instead:

final String whatever = someCondition ? "final value" : "other value" 

Which is fine for that limited use case, but totally untenable once you start dealing with switch statements and multiple constructors.


Scala's approach is different here. All object construction must ultimately pass through a single "primary" constructor, all expressions return a value (even if it's Unit, equivalent to Java's Void), and constructor injection is strongly favoured. This results in object graphs being cleanly built as a Directed Acyclic Graph, and also works very nicely with immutable objects.

You also want to be aware that declaring and defining variables in separate operations is, in general, a bad practice when dealing with multiple threads - and could leave you vulnerable to exposing nulls and race conditions when you least expect them (though this isn't really a problem during object construction). The atomic creation of immutable values is just one aspect of the way in which functional languages help to to deal with concurrency.

It also means that the Scala compiler can avoid some of the hideously complicated flow analysis from the Java language spec.

As previously stated, the Scala Way™ is:

val whatever =   if (someCondition)     "final value"   else     "other value" 

An approach which also scales up to other control structures:

val whatever = someCondition match {   case 1 => "one"   case 2 => "two"   case 3 => "three"   case _ => "other" } 

With a bit of Scala experience you'll discover that this style helps the compiler to help you, and you should find yourself writing programs with fewer bugs!

like image 31
Kevin Wright Avatar answered Sep 22 '22 02:09

Kevin Wright