2013-09-03 2 views
0

delayedInit에서 다양한 게시물을 읽었을 때, 저는 실제로 건설 중에 다양한 서브 클래스에 의해 매번 호출된다는 사실에 놀랐습니다. 나는 이것을 믿었는지 확신 할 수 없었지만 그 다음에 아래 테스트를 만들었습니다. 어쨌든, 제 질문은 delayedInit은 추상 클래스에서 어떤 종류의 최종 동작을 유도하는 유용한 메커니즘처럼 들리는 것입니다 (예 : 생성 완료의 다른 개체를 알리는 것과 같음). 그리고 한번만 부름을 받았다면 말이 될 것입니다. 그러나 매개 변수로 전달되는 다른 유용한 정보없이 반복적으로 호출 될 위험이있는 경우 함수에서 유용한 구성을 만들 수 있습니까? 어떻게하면 A 클래스가 얼마나 깊이 확장되었는지를 알지 못해도 마지막 레벨의 빌딩에서만 발사하도록 프로그래밍 할 수 있습니까?그럼 delayedInit을 안전하게 사용할 수 있습니까?

object LearnDelayedInit extends App { 

    class A extends DelayedInit { 
    def delayedInit(x: => Unit) { 
     x // call constructor code 
     println("delayed init called") 
    } 
    } 

    class B extends A {   
    println("Hello from B")  
    } 

    class C extends B {  
    println("hello from C") 
    } 

    val c = new C  
} 

출력 : 만 초기화 코드

object LearnDelayedInit extends App { 

    trait A extends DelayedInit { 
    def delayedInit(x: => Unit) { 
     x //call constructor code 
     println("delayed init called") 
    } 
    } 

    trait B extends A { 
    println("Hello from B") 
    } 

    class C extends B { 
    println("hello from C") 
    } 

    val c = new C 
} 

: 당신이 특성에서 계층 구조를 만들기 만 잎이 클래스를 입력하면

Hello from B  
delayed init called  
hello from C  
delayed init called 
+0

이것은 수사학적인 질문이지만 "유용한 구조"에는 '앱'이 포함되어 있습니까? –

+0

예 저는 App이 어떻게 든 이걸 사용한다는 것을 알고 있습니다. 그러나 솔직히 아직도 방법을 파악하려고합니다. 또한 다른 종류의 용도가 존재 하는지를 알고 싶습니다. – LaloInDublin

+0

이상한 메커니즘이며 버그가 없습니다 (하, 목록 있음). 또한 개념이 단순합니다. 이니셜 라이저는 delayedInit에 대한 호출이됩니다. App에서 main은 delayedInit impl으로 수집 된 모든 코드를 호출합니다. 내 대답은 미래에 각 초기화 프로그램을 실행합니다. 유스 케이스가 있는지 모르겠지만 질문에 감사드립니다. 대답을 생각하는 것이 재미있었습니다. –

답변

1

여기 있습니다.

앞으로의 것들은 천재를위한 것입니다.

기본 아이디어는 val doneC의 이니셜 라이저 또는 하단 클래스가 무엇이든 정확하게 초기화된다는 것입니다.

한 질문을 The One Question FAQ으로 읽었습니다.

object Test extends App { 

    import java.util.concurrent.{ CountDownLatch => Latch } 

    trait FutureInit { 
    import concurrent._ 
    import ExecutionContext.Implicits._ 
    private var fs = future(()) 
    def done: Boolean 
    val latch = new Latch(1) 
    def delayedInit(x: => Unit) { 
     fs = fs andThen { 
     case _ => 
      x 
      if (done) { println("All done!") ; latch.countDown() } 
     } 
    } 
    } 

    class A extends DelayedInit with FutureInit { 
    println("Hello from A") 
    Thread sleep 500L 
    override val done = true 
    } 

    class B extends A { 
    println("Hello from B") 
    Thread sleep 500L 
    override val done = true 
    } 

    class C extends B { 
    println("hello from C") 
    Thread sleep 500L 
    override val done = true 
    } 

    val c = new C 
    c.latch.await() 
    println("Good bye.") 

    val b = new B 
    b.latch.await() 
    println("That's all, folks. Go home.") 
} 
3

가 원하는 동작을 얻을 것이다 클래스가 래핑되어 delayedInit으로 전달되면 형질은 평상시대로 생성자에서 초기화 코드가 실행됩니다.

+0

감사합니다. 훌륭한 정보! 마크를 받았다. 두 답은 모두 내 질문의 한 부분을 다룬다. – LaloInDublin

관련 문제