jules
jules

Reputation: 447

Assign values of a tuple to single variables in Scala

is there a nice possibilyt to assign the values of a tuple to single variables? Here is what i want to do but it throws an error:


var a : Int = _
var b : Int = _

def init() {
   (a,b) = getTuple() // returns (Int, Int)
}

def someFunction = {    
    // use a here
}


def someOtherFunction = {    
    // use b here
}
Error: ';' expected but '=' found.
    (a, b) = getTuple()

Do i really have to do this ._1 and ._2 thing?


val tuple = getTuple() // returns (Int, Int)
a = tuple._1
b = tuple._2

Thanks for answering.

Upvotes: 0

Views: 693

Answers (2)

Jörg W Mittag
Jörg W Mittag

Reputation: 369614

As you can see in Section 6.15 Assignments of the Scala Language Specification, the lefthand-side of an assignment expression must be either a bare identifier:

foo = ???
// either an assignment to a local mutable `var` or syntactic sugar for:
foo_=(???)

a member access:

foo.bar = ???
// syntactic sugar for:
foo.bar_=(???)

or a method call:

foo(bar) = ???
// syntactic sugar for:
foo.update(bar, ???)

Pattern Matching is only available for value definitions (see Section 4.1 Value Declarations and Definitions) and variable definitions (see Section 4.2 Variable Declarations and Definitions).

So, both of the following would be legal:

var (a, b) = getTuple()
val (a, b) = getTuple()

By the way, there are a number of highly non-idiomatic things in your code:

  • It is highly unusual to pass an empty argument list to a method call. Normally, methods that have no parameters should have no parameter lists instead of an empty parameter list. The only exception are methods that have side-effects, where the empty parameter list serves as kind of a "warning flag", but methods which have side-effects are highly non-idiomatic as well. So, getTuple should be defined and called like this:
    def getTuple = ???
    getTuple
    
    instead of
    def getTuple() = ???
    getTuple()
    
  • On the other hand, if the method does have side-effects, it shouldn't be called getTuple because that implies that the method "gets" something, and there is no indication that it also changes something.
  • In Scala, getters and setters are not called getFoo and setFoo but rather foo and foo_=, so the method should rather be called tuple.
  • Mutable variables are highly non-idiomatic as well, they should probably rather be vals.

Upvotes: 2

goodmove
goodmove

Reputation: 161

Tuple destructuring is an opaque call to unapply method of TupleN[T1, ..., Tn] companion object, aka extractor object. As the documentation suggests, one can only have a variable initialization with an extractor object, but not assignment.

So, the only possible way is to use it like this:

def getTuple = (1,2)

def main() = {
    val (a,b) = getTuple
    // use a,b
}

The fact that you use a var may be the sign you have a design flaw. Try to refactor your code or specify the exact problem you're trying to solve with the var to justify its usage (although what you're trying to do with extractor is still impossible)

Upvotes: 1

Related Questions