2014-03-04 1 views

답변

8

예 Scala가 클래스를 구성하고 초기화하는 방식으로 인해 의도 된 동작입니다. 클래스 B에 아직 초기화되지 않은 반면, 값이 초기화 된 기능 f 클래스 C에서 호출되는 순간

scala> class A { 
    | f 
    | 
    | implicit val arg = "foo" 
    | 
    | def f(implicit arg: String) = { 
    |  println(arg) 
    | } 
    | } 
defined class A 

scala> class B { 
    | f(arg) 
    | 
    | val arg = "foo" 
    | 
    | def f(implicit arg: String) = { 
    |  println(arg) 
    | } 
    | } 
defined class B 

scala> class C { 
    | implicit val arg = "foo" 
    | 
    | f 
    | 
    | def f(implicit arg: String) = { 
    |  println(arg) 
    | } 
    | } 
defined class C 

scala> new A 
null 
res0: A = [email protected] 

scala> new B 
null 
res1: B = [email protected] 

scala> new C 
foo 
res2: C = [email protected] 

이 예를 생각해 보자. A 클래스는 정확히 B 클래스와 동일합니다. 유일한 차이점은이 A에 암시 적으로 전달된다는 것입니다.

이 코드는 멤버 변수를 선언하고 생성자 코드를 실행하기 때문에 2 가지 일을하기 때문에 다소 혼란 스럽습니다. 예를 들어 클래스 B을 가져 오는 경우 val argf이 호출되었지만 아직 초기화되지 않은 지점에서 선언됩니다. val arg = "foo" 초기화를 수행합니다. 자바이 번역되면 그것은 더 분명하게 : 도움이 될 것입니다 lazy val 또는 올바른 초기화 순서를 사용

public class B { 

    void f(String arg) { 
     System.out.println(arg); 
    } 

    String arg; // also acts as final in Scala 

    public B() { 
     f(arg); 
     arg = "foo"; 
    } 
} 

가 그것을 해결하기 위해 :

scala> class B { 
    | f(arg) 
    | 
    | lazy val arg = "foo" 
    | 
    | def f(implicit arg: String) = { 
    |  println(arg) 
    | } 
    | } 
defined class B 

scala> new B 
foo 
res3: B = [email protected] 
+2

특성을 적재 할 때 매우 짜증나는 일 수있다 2.11. 당신은 그것을 수정하기 위해'게으른 val'을 만들 수 있습니다. –

+0

게으른 예를 들어 대답을 업데이트했습니다. –

+1

특성과 더 복잡한 시나리오를 사용하면 이상한 결과가 나옵니다. 또 하나의 수정은 적절할 때'def'를 사용하는 것입니다. –

관련 문제