In Java I often find myself assigning to multiple final variables in each branch of a conditional like so:
final _ x;
final _ y;
if (_) {
x = _;
y = _;
} else {
x = _;
y = _;
}
In Scala I am aware that a single val can be assigned using the technique:
val x = {
if (_) {
_;
} else {
_;
}
}
In fact, the above method can be modified to assign to multiple variables by having the block return a tuple that is pattern matched to variables like:
{
if (_) {
_;
} else {
_;
}
} match { case (x, y) => _ }
But I find this syntax to be quite awkward. Is there a simpler way, ideally similar to the Java code, to do what I want?
scala> val (x,y) = if (true) (3,"blah") else (1,"blis")
x: Int = 3
y: String = blah
It looks like a tuple assignment but it's actually assigning to multiple vals. (OK, it's actually both.)
Yes, you can specify multiple instances that you want your values to be assigned to, much like the cases in a match statement (and using the same underlying concept - unapply). THe most typical way you see this is done is in the form of a deconstructed tuple, such as (incorporating the if-else as per your question):
val (x,y,z) = if (true) (x_value, y_value, z_value) else (alt_x, alt_y, alt_z)
(much as shown in @jwvh's answer)
This can be taken further, to utilise the unapply method for any data type that has it (including all case classes). Eg:
scala> val head :: tail = if (true) List(3,4,5,6) else List(9,8,7)
head: Int = 3
tail: List[Int] = List(4, 5, 6)
or
scala> case class Foo(ix: Int, bar: String)
defined class Foo
scala> val f@Foo(the_ix, the_bar) = if (true) Foo(2, "baz") else Foo(5, "wibble")
f: Foo = Foo(2,baz)
the_ix: Int = 2
the_bar: String = baz
scala> f
res3: Foo = Foo(2,baz)
scala> the_ix
res4: Int = 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With