2014-01-28 4 views
7

Я начинаю scala и пытаюсь понять, как val работает в Scala. Я читал, что валы не могут быть изменены. Когда я делаю следующее:Scala: объявление val внутри цикла цикла, если условие

for(line <- Source.fromFile(args(0)).getLines()) { 
    val currentLine = line 
    println(currentLine) 
} 

CurrentLine обновляется на каждой итерации, в то время как я ожидаю, что это будет инициализирован с первой линией и удерживать ее до конца, или, по крайней мере, дать ошибку повторной инициализации какой-то , Почему это так? Является ли val создан и уничтожен на каждой итерации? Мой второй вопрос: я хотел бы использовать x вне, если в следующем коде.

if(some condition is satisfied) val x = 2 else val x = 3 

На данный момент я получаю сообщение об ошибке «Незаконный старт простого выражения». Есть ли способ использовать x снаружи, если?

+0

Чтобы быть ясным, разница между 'val' и' var' заключается в том, что 'val' не может быть переназначен. –

+0

Помните, что 'val currentLine = line' не совпадает с' currentLine = line' в изоляции. Только последний пытается присвоить новое значение существующему значению. – KChaloux

ответ

12
  1. Да, на каждой итерации создается и уничтожается val.

  2. val x = if(condition) 2 else 3 будет делать то, что вы хотите.

Edit: Вы можете переписать 2. if(conditon) {val x = 2} else {val x = 3} (чтобы собрать), но это не будет делать ничего, так как если не возвращает ничего и переменная не может быть использована за пределами if

0

первый вопрос: да, в каждой итерации создается новый вал

второй вопрос: вы могли бы переписать это

val x = if (some condition is satisfied) 
    2 
else 
    3 
2

Для петли

Вы можете разбить ее на операцию map.

for(line <- Source.fromFile(args(0)).getLines()) { 
    val currentLine = line 
    println(currentLine) 
} 

Так что этот код преобразуется в

Source.fromFile(args(0)).getLines().map(line => block) 

block может быть любое выражение. Где в вашем случае block является:

{ 
    val currentLine = line 
    println(currentLine) 
} 

Здесь currentLine локально для block и создаются для каждого из значений line данных для map операции.

If-Else

Опять следующий тоже неправильно:

if(some condition is satisfied) val x = 2 else val x = 3 

По существу if-else в Scala возвращает значение.Так оно и должно быть:

if(condition) expression1 else expression1 

В вашем случае это может быть:

if(condition) { val x = 2 } else { val x = 3 } 

Однако задание возвращает Unit (или void, если вы хотите провести аналогию с Java/C++). Таким образом, вы можете просто взять значение if-else так:

val x = if(condition) { 2 } else { 3 } 
// OR 
val x = if(condition) 2 else 3 
1

ответа не упомянул об этом, так в дополнение к тому, что было сказано:

  1. val становится доступным для сбора мусора на каждой итерации (и, следовательно, недоступен из следующей итерации цикла). Это связано с тем, что называется scope of variables, которое ограничено блоком в scala (аналогично Java).

  2. Как указано @Kigyo val x = if(condition) 2 else 3 будет делать то, что вы хотите, потому что вы выполняете только одно назначение. Если вы помещаете привязку в val в блоки, тогда область действия этого val является блоком и, следовательно, не может использоваться так, как вы хотите.

+2

Относительно (1): Если бы это было правдой! Компилятор не заменяет ссылочные локаторы на «null», когда выполнение выходит из области действия. Это может иногда вызвать симптомы, подобные утечке памяти. –

+0

Хорошо, так что, может быть, я должен перефразировать его: val обычно разрушается на каждой итерации? – benzonico

+0

Не так много «уничтожено», как «сделано для сбора мусора» –

Смежные вопросы