Возможный дубликат:
Scala и прямые ссылки
Есть ли какое-то объяснение, почему в Scala работает следующее:
Версия 1
object Strange extends App {
val x = 42
Console.println(x) // => outputs "42", as expected
}
Версия 2
object Strange extends App {
Console.println(x) // => "0" ?!
val x = 42
}
Почему он вообще компилируется и почему ведет себя так странно без каких-либо предупреждений или чего-то подобного?
Та же проблема с class
:
class StrangeClass {
Console.println(x) // => still "0"
val x = 42
}
object TestApp extends App {
new StrangeClass()
}
С телом обычного метода такой проблемы нет:
def nonStrangeMethod {
Console.println(y) // => fails with "not found: value y", as expected
y = 42
}
И поведение резко изменится, если мы добавим «final» к объявлению val:
class StrangeClass {
Console.println(x) // => "42", but at least that's expected
final val x = 42
}
Для записей следующий статический аналог Java (Scala object
):
public class Strange {
static {
System.out.println(x);
}
static int x = 42;
public static void main(String[] args) {}
}
не удается выполнить компиляцию с простой и понятной ошибкой «Невозможно ссылаться на поле до его определения» в строке № 3 и нестатическом аналоге Java (Scala class
):
public class Strange {
Strange() {
System.out.println(x);
int x = 42;
}
public static void main(String[] args) {
new Strange();
}
}
явно терпит неудачу с "x не может быть преобразован в переменную" в строке № 3.
App
, иobject
здесь не проблема. Я могу воспроизвести точно такое же поведение с помощью конструктораclass
без каких-либо трейтов. Таким образом, поведение, которое вы указываете, похоже, относится к любому коду, подобному конструктору. 22.11.2012