1

I want to do this:

var (a, b) = (0, 0)
a = (b = 100) 

but Scala is complaining that

error: type mismatch;
 found   : Unit
 required: Int

What I want is to assign a and b to the same value. Why Scala make it Unit where it should be Int?

Phương Nguyễn
  • 8,747
  • 15
  • 62
  • 96

5 Answers5

5

Your statement is an assignment, which returns Unit. See this related question for reasons why. You can do this, if you want:


scala> var (a,b) = (0,0)
a: Int = 0
b: Int = 0

scala> a = {b = 100; b}
a: Int = 100
Community
  • 1
  • 1
Arjan Blokzijl
  • 6,878
  • 2
  • 31
  • 27
3
scala> var a,b,c,d,e,f,g = 0
a: Int = 0
b: Int = 0
c: Int = 0
d: Int = 0
e: Int = 0
f: Int = 0
g: Int = 0

scala> var f,i,j,k,m,n,o = new Object{}
f: java.lang.Object = $anon$1@11ce012
i: java.lang.Object = $anon$2@baf4ae
j: java.lang.Object = $anon$3@15e68d
k: java.lang.Object = $anon$4@1d3633c
m: java.lang.Object = $anon$5@118317f
n: java.lang.Object = $anon$6@15998cb
o: java.lang.Object = $anon$7@13e6f83

scala>
Eastsun
  • 18,526
  • 6
  • 57
  • 81
2

Why ask why? Assignment expressions have type Unit and that's how it is. No chained assignments. Period.

Randall Schulz
  • 26,420
  • 4
  • 61
  • 81
  • 2
    Why ask why? Because I find it doesn't make sense. Java has it, Ruby has it, why Scala make it different? – Phương Nguyễn Jul 25 '10 at 16:49
  • 2
    Because Scala doesn't want to be those languages. It's the same reason Scala doesn't have a break statement; to encourage you to leave the imperative baggage you brought from Java and Ruby at the door. – Tom Crockett Jul 25 '10 at 18:07
  • 1
    Weeeelllll, I hate to bring it up, but Scala has a break statement nowadays (since 2.8). But you have to import it (import scala.util.control.Breaks._) so I guess no one will ever use it, and that is probably exactly what was intended :-) – olle kullberg Jul 25 '10 at 19:11
2

You can define a special assignment operator (it must end with a colon as it must be right associative) for your own types, or write a generic wrapper (including implit conversions) for general types. I wouldn't recommend to actually use this, but here it goes:

  case class M[T](var t:T) {
    def =: (m: M[T]):M[T] = {m.t = t ; this}
  }

  implicit def anyToM[T](v:T) = M(v)
  implicit def mToAny[T](m:M[T]) = m.t

  def main(args: Array[String]) {
    var a = M(0)
    var b = M(0)
    var c = M(0)
    a =: b =: c =: 100
    println(a + b + c) //--> 300
  }

I think it is always a bad idea to summon heavy magick in order to save a few keystrokes. In Germany we would call this "to shoot sparrows with a cannon"...

Landei
  • 54,104
  • 13
  • 100
  • 195
1
case class assign[T](v: T) {                           
  def to(vals: (T => Unit)*) { vals.foreach{ vv => vv(v) } }
}

var (a,b) = (0,0)

assign(39) to (a = _, b = _)

assert(a == 39)
assert(b == 39)

Or you can rename it to emulate a rather simple version of a with statement.

with(20) do (a = _, b = _, print)
Debilski
  • 66,976
  • 12
  • 110
  • 133