2012-06-25 5 views
7

Я понимаю, что параметрические поля (например, x в приведенном ниже примере) ведут себя как обычные поля; так что вы можете ссылаться на них в методах:Параметрические поля Scala и аргументы конструктора

class Test(val x: Int) { // x is a parametric field 
    override def toString = "Test: " + x; 
} 

Однако, если вы уронили ключевое слово val, код по-прежнему компилируется (и смотреть и .class выход, x еще член класса). Поэтому мне интересно, в чем разница между параметрическими полями (т. Е. val x: Int в приведенном выше) и аргументами конструктора (x: Int)?

(с Java в задней части моей головы, я ожидал бы сферу конструктора как x к не включают в себя метод, как toString.)

+0

Я считаю, 'x' все еще приходит член, если на него ссылаются хотя бы на 1 метод, независимо от того, предиффицирован ли он 'val' или нет. – adelbertc

ответ

9

Без val ключевого слова, ваш код похож на : class Test (private[this] val x: Int) { ... }. Поэтому x доступен во всем классе, но не снаружи.

Это не указано в вашем вопросе, но оно также может быть полезно: в case class модификатор по умолчанию - val. Таким образом, case class Test(x: Int) {...} эквивалентен case class (val x: Int) {...}.

+2

Эквивалент минус все остальное, что «класс дела», конечно. :-) –

+0

@ DanielC.Sobral На самом деле, я не уточнил это, потому что опечатка, которую вы исправили, на самом деле не была опечаткой. ;) – Nicolas

2

Параметр конструктора эффективно становится полем private[this], но только в том случае, если имеется ссылка хотя бы на один метод. В противном случае поле не генерируется в классе.

Например:

class Foo(i: Int) { 
    println(i) 
} 

становится

$ javap -private Foo 
Compiled from "Foo.scala" 
public class Foo extends java.lang.Object implements scala.ScalaObject{ 
    public Foo(int); 
} 

Но

class Bar(i: Int) { 
    def baz = println(i) 
} 

становится

$ javap -private Bar 
Compiled from "Bar.scala" 
public class Bar extends java.lang.Object implements scala.ScalaObject{ 
    private final int i; 
    public void baz(); 
    public Bar(int); 
} 
Смежные вопросы