Scala assignments
I felt like a weird snippet in Scala that I don't quite understand. For me the assignments are in Scala return Unit
, as opposed to Java, where it returns the type of the variable that was affected by the value. However, consider this class:
case class C(i: Int) {
def f = C(i = i + 10)
}
This compiles completely, which is pretty weird! The factory method C.apply
expects Int
, whereas I pass it what appears to be an assignment, like Unit
. By the way, if I remove the assignment to just express this expression, it appears to have the same behavior.
Try this now:
case class C(i: Int) {
def f = {
i = i + 10
C(i = i + 10)
}
}
Ok, now this is the world I know: i
is val, then you can't mutate it, so it i = i + 10
doesn't compile. However, C(i = i + 10)
it still compiles without complaints. What is this weirdness? Is there a reason for this?
source to share
This is because in the case, the C(i = i + 10)
left i
one is not a field C#i
, but a named parameter . No assignment is performed at all.
C(i = i + 10)
^ ^
+---|-------- Parameter name
|
+- - - - - - - - - - - - - - Reference to the field `i`
in the instance of the class `C`
In some places where named parameters make sense:
-
Avoiding "what does it
{boolean, integer}
mean" moment:someMethod(anObject, flagName=true) // As opposed to someMethod(anObject, true) ... what `true` for? anotherMethod(arg1, arg2, totalMagic=33)
-
When using default values for parameters (to call the right constructor):
def withDefaults(i: Int, flag: Boolean = true, wrapper: Option[String] = None) = { wrapper.fold(s"$i with $flag")(_.format(i, flag)) } withDefaults(3, Some("stuff %s around %s")) // won't compile // error: type mismatch; // found : Some[String] // required: Boolean withDefaults(3, wrapper = Some("stuff %s around %s")) // works (returns "stuff 3 around true")
source to share