Scala параллельные присваивания только в объявлениях - PullRequest
5 голосов
/ 21 апреля 2011

Имея:

def f () = {
    (1, "two", 3.0)
}

Почему это нормально

var (x, y, z) = f()

но не


var i = 0
var j = "hello"
var k = 0.0

// use i, j, k
...
//then
(i, j, k) = f() // ; expected but = found

?

Ответы [ 2 ]

6 голосов
/ 21 апреля 2011

Вы видите здесь ограниченную версию сопоставления с образцом при инициализации переменных. Обратите внимание, что это работает не только для кортежей:

val a :: b = List(1,2,3)
println(a) //1
println(b) //List(2, 3)

Эта функция заимствована непосредственно из Haskell, где вы также можете использовать шаблоны для инициализации:

let (a,b) = getTuple 
in a*b

Поскольку у Haskell нет изменяемых данных, нет способа присвоить что-либо.

В Scala вы могли бы сделать что-то подобное, но я думаю, это было слишком запутанным или, возможно, слишком сложным для реализации. Вы всегда можете использовать выражение match как обычно, и часто вам нужно просто case, например, List((1,2),(3,4)).map{ case (a,b) => a*b }.

2 голосов
/ 21 апреля 2011

Я подозреваю, что без «var» или «val» слева от кортежа имен переменных компилятор обрабатывает кортеж как кортеж. То есть вы действительно пытаетесь присвоить значение экземпляру Tuple3, а не трем переменным, и это не имеет смысла для компилятора.

Кстати, использование функции и различных типов данных в вашем примере не имеет значения. Вот более простой пример:

scala> var ( i, j, k ) = ( 1, 2, 3 )
i: Int = 1
j: Int = 2
k: Int = 3

scala> ( i, j, k ) = ( 4, 5, 6 )
<console>:1: error: ';' expected but '=' found.
       ( i, j, k ) = ( 4, 5, 6 )
                   ^
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...