복붙노트

[SCALA] 게으른 발은 무엇입니까?

SCALA

게으른 발은 무엇입니까?

나는 스칼라 게으른 놈들을 제공하는 것으로 나타났습니다. 그러나 나는 그들이 무엇을하지 않습니다.

scala> val x = 15
x: Int = 15

scala> lazy val y = 13
y: Int = <lazy>

scala> x
res0: Int = 15

scala> y
res1: Int = 13

REPL은 y는 게으른 발 것을 보여 주지만, 어떻게 정상적인 발 다른가?

해결법

  1. ==============================

    1.이들 사이의 차이는 처음 액세스 할 때 지연 브로가 실행되는 반면,이 정의 될 때 발을 실행한다는 것이다.

    이들 사이의 차이는 처음 액세스 할 때 지연 브로가 실행되는 반면,이 정의 될 때 발을 실행한다는 것이다.

    scala> val x = { println("x"); 15 }
    x
    x: Int = 15
    
    scala> lazy val y = { println("y"); 13 }
    y: Int = <lazy>
    
    scala> x
    res2: Int = 15
    
    scala> y
    y
    res3: Int = 13
    
    scala> y
    res4: Int = 13
    

    방법에 대조적 지연 브로 번 후 결코 다시 실행된다 (DEF 정의). 작업이 완료하는 데 시간이 오래 걸립니다 때 나중에 사용하는 경우가 확실하지 않을 때 유용 할 수 있습니다.

    scala> class X { val x = { Thread.sleep(2000); 15 } }
    defined class X
    
    scala> class Y { lazy val y = { Thread.sleep(2000); 13 } }
    defined class Y
    
    scala> new X
    res5: X = X@262505b7 // we have to wait two seconds to the result
    
    scala> new Y
    res6: Y = Y@1555bd22 // this appears immediately
    

    여기서 x와 y에 사용하지 않을 경우에만 불필요하게 자원을 낭비 X. 우리는 y는 부작용이 없다고 가정하고 우리가 액세스 빈도를 모르는 경우 (결코 한 번, 수천 번) 우리가 그것을 여러 번 실행하지 않기 때문에 데프로 선언하는 것이 쓸모가 없습니다.

    당신이 어떻게 구현되는지 게으른 놈들 알고 싶다면,이 질문을 참조하십시오.

  2. ==============================

    2.이 기능은 고가의 계산을 지연뿐만 아니라 도움뿐만 아니라 상호 의존 또는 고리 형 구조를 구축하는 데 유용합니다. 예를 들면 이것은 스택 오버 플로우로 연결 :

    이 기능은 고가의 계산을 지연뿐만 아니라 도움뿐만 아니라 상호 의존 또는 고리 형 구조를 구축하는 데 유용합니다. 예를 들면 이것은 스택 오버 플로우로 연결 :

    trait Foo { val foo: Foo }
    case class Fee extends Foo { val foo = Faa() }
    case class Faa extends Foo { val foo = Fee() }
    
    println(Fee().foo)
    //StackOverflowException
    

    그러나 게으른 놈들과 그것을 잘 작동합니다

    trait Foo { val foo: Foo }
    case class Fee extends Foo { lazy val foo = Faa() }
    case class Faa extends Foo { lazy val foo = Fee() }
    
    println(Fee().foo)
    //Faa()
    
  3. ==============================

    3.나는 대답이 주어진하지만 난 나 같은 초보자를위한 이해하기 쉽게하기 위해 간단한 예를 쓴 것을 이해 :

    나는 대답이 주어진하지만 난 나 같은 초보자를위한 이해하기 쉽게하기 위해 간단한 예를 쓴 것을 이해 :

    var x = { println("x"); 15 }
    lazy val y = { println("y"); x+1 }
    println("-----")
    x = 17
    println("y is: " + y)
    

    위의 코드의 출력은 다음과 같습니다

    x
    -----
    y
    y is: 18
    

    이 볼 수 있듯이이 초기화 때, x가 인쇄되어 있지만,이 같은 방법으로 초기화 할 때 y는 인쇄되지 않습니다 (- Y가 초기화됩니다 때 설명하기 위해 나는 의도적으로 여기 var과 같은 x를 촬영했다). 마지막으로 'X'의 Y를 호출 할 때 다음에, 초기화 것뿐만 아니라 값이 이전을 고려하지만,하지 않습니다.

    도움이 되었기를 바랍니다.

  4. ==============================

    4.게으른 브로 가장 쉽게 "DEF memoized (인수 없음)"는 것으로 이해된다.

    게으른 브로 가장 쉽게 "DEF memoized (인수 없음)"는 것으로 이해된다.

    가 호출 될 때까지 데프처럼 게으른 발은 평가되지 않습니다. 그러나 결과는 이후의 호출은 저장된 값을 반환하도록 저장됩니다. memoized 결과는 발과 같은 데이터 구조에서 공간을 차지합니다.

    다른 언급했듯이, 게으른 발에 대한 사용 사례가 필요할 때까지 비용 계산을 연기하고 결과를 저장하고, 값 사이에 특정 순환 종속성을 해결한다.

    게으른 놈들은 사실 memoized 인증 된 정의로 더 많거나 적은을 구현됩니다. 현재 구현의 세부 사항에 대해 읽을 수 있습니다 :

    http://docs.scala-lang.org/sips/pending/improved-lazy-val-initialization.html

  5. ==============================

    5.또한 다음 코드와 같이 순환 의존하지 않고 유용 게으른 :

    또한 다음 코드와 같이 순환 의존하지 않고 유용 게으른 :

    abstract class X {
      val x: String
      println ("x is "+x.length)
    }
    
    object Y extends X { val x = "Hello" }
    Y
    

    X는 아직 초기화되지 않기 때문에 Y 액세스 지금, 널 포인터 예외가 발생합니다. 다음은, 그러나, 잘 작동 :

    abstract class X {
      val x: String
      println ("x is "+x.length)
    }
    
    object Y extends X { lazy val x = "Hello" }
    Y
    

    편집 : 다음은 또한 작동합니다 :

    object Y extends { val x = "Hello" } with X 
    

    이는 "초기 초기화"라고합니다. 자세한 내용은이 SO 질문을 참조하십시오.

  6. ==============================

    6.위의 정의 - - 게으른의 데모는 실행 액세스 할 때 실행 대 정의 할 때 : (2.12.7 스칼라 쉘을 사용)

    위의 정의 - - 게으른의 데모는 실행 액세스 할 때 실행 대 정의 할 때 : (2.12.7 스칼라 쉘을 사용)

    // compiler says this is ok when it is lazy
    scala> lazy val t: Int = t 
    t: Int = <lazy>
    //however when executed, t recursively calls itself, and causes a StackOverflowError
    scala> t             
    java.lang.StackOverflowError
    ...
    
    // when the t is initialized to itself un-lazily, the compiler warns you of the recursive call
    scala> val t: Int = t
    <console>:12: warning: value t does nothing other than call itself recursively
       val t: Int = t
    
  7. ==============================

    7.

    scala> lazy val lazyEight = {
         |   println("I am lazy !")
         |   8
         | }
    lazyEight: Int = <lazy>
    
    scala> lazyEight
    I am lazy !
    res1: Int = 8
    
  8. from https://stackoverflow.com/questions/7484928/what-does-a-lazy-val-do by cc-by-sa and MIT license