복붙노트

[SCALA] 어떻게 스칼라 2.10에서 구현 게으른 발 클래스 변수는?

SCALA

어떻게 스칼라 2.10에서 구현 게으른 발 클래스 변수는?

스칼라의 게으른 발의 (숨겨진) 비용 무엇이 답? 그들은 스칼라 2.7에 구현 된 방법을 보여줍니다. 코멘트가 말한대로하지만, 이것이 궁금 해요, 그래서 클래스 게으른 발 변수의 현재 (2.10) 구현은 무엇입니까, 그 이후로 변경해야합니까?

해결법

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

    1.스칼라 2.10.2 이것을 컴파일 :

    스칼라 2.10.2 이것을 컴파일 :

    class Foo {
    
      lazy val bar = math.pow(5, 3)
    
    }
    

    그리고 JD-GUI와 결과를 디 컴파일 :

    import scala.math.package.;
    import scala.reflect.ScalaSignature;
    
    @ScalaSignature(bytes="\006\001e1A!\001\002\001\013\t\031ai\\8\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\rC\003\016\001\021\005a\"\001\004=S:LGO\020\013\002\037A\021\001\003A\007\002\005!A!\003\001EC\002\023\0051#A\002cCJ,\022\001\006\t\003\017UI!A\006\005\003\r\021{WO\0317f\021!A\002\001#A!B\023!\022\001\0022be\002\002")
    public class Foo {
    
        private double bar;
        private volatile boolean bitmap$0;
    
        private double bar$lzycompute() {
            synchronized (this) { 
                if (!this.bitmap$0) { 
                    this.bar = package..MODULE$.pow(5.0D, 3.0D); 
                    this.bitmap$0 = true; 
                } 
                return this.bar; 
            }  
        } 
    
        public double bar() { 
            return this.bitmap$0 ? this.bar : bar$lzycompute(); 
        }
    
    }
    

    편집 - 여기 세 필드의 모습입니다 :

    class Foo {
    
      lazy val a = math.pow(5, 1)
      lazy val b = math.pow(5, 2)
      lazy val c = math.pow(5, 3)
    
    }
    

    디 컴파일 :

    import scala.math.package.;
    import scala.reflect.ScalaSignature;
    
    @ScalaSignature(bytes="\006\001\0052A!\001\002\001\013\t\031ai\\8\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\rC\003\016\001\021\005a\"\001\004=S:LGO\020\013\002\037A\021\001\003A\007\002\005!A!\003\001EC\002\023\0051#A\001b+\005!\002CA\004\026\023\t1\002B\001\004E_V\024G.\032\005\t1\001A\t\021)Q\005)\005\021\021\r\t\005\t5\001A)\031!C\001'\005\t!\r\003\005\035\001!\005\t\025)\003\025\003\t\021\007\005\003\005\037\001!\025\r\021\"\001\024\003\005\031\007\002\003\021\001\021\003\005\013\025\002\013\002\005\r\004\003")
    public class Foo {
    
        private double a;
        private double b;
        private double c;
    
        private volatile byte bitmap$0;
    
        private double a$lzycompute() {
            synchronized (this) {
                if ((byte)(this.bitmap$0 & 0x1) == 0) {
                    this.a = package..MODULE$.pow(5.0D, 1.0D); 
                    this.bitmap$0 = ((byte)(this.bitmap$0 | 0x1)); 
                } 
                return this.a;
            }  
        } 
    
        private double b$lzycompute() { 
            synchronized (this) {
                if ((byte)(this.bitmap$0 & 0x2) == 0) {
                    this.b = package..MODULE$.pow(5.0D, 2.0D); 
                    this.bitmap$0 = ((byte)(this.bitmap$0 | 0x2)); 
                } 
                return this.b; 
            }  
        } 
    
        private double c$lzycompute() { 
            synchronized (this) {
                if ((byte)(this.bitmap$0 & 0x4) == 0) {
                    this.c = package..MODULE$.pow(5.0D, 3.0D); 
                    this.bitmap$0 = ((byte)(this.bitmap$0 | 0x4)); 
                } 
                return this.c;
            }
        }
    
        public double a() {
            return (byte)(this.bitmap$0 & 0x1) == 0 ? a$lzycompute() : this.a;
        }
    
        public double b() { 
            return (byte)(this.bitmap$0 & 0x2) == 0 ? b$lzycompute() : this.b; 
        } 
    
        public double c() { 
            return (byte)(this.bitmap$0 & 0x4) == 0 ? c$lzycompute() : this.c;
        }
    
    }
    
  2. ==============================

    2.업데이트 스칼라 2.12.1 (12 월 2016 3 년 후에).

    업데이트 스칼라 2.12.1 (12 월 2016 3 년 후에).

    PR 5294 (필드 단계가 완전히 게으른 놈들과 모듈을 확장) 후 743f0d2 커밋, 당신은 읽을 수 있습니다 :

    class C { def foo = {lazy val x = {println("a"); "A" }; x } }
    
    def foo(): String = {
      lazy <artifact> val x$lzy: scala.runtime.LazyRef[String] = new scala.runtime.LazyRef[String]();
    
      <artifact> private def x$lzycompute(): String =
        x$lzy.synchronized[String]{
          if (x$lzy.initialized())
            x$lzy.value() // NOTE: gets an `.asInstanceOf[String]` after erasure
          else
            {
              x$lzy.value_=({
                scala.Predef.println("a");
                "A"
              });
              x$lzy.initialized_=(true);
              x$lzy.value() // NOTE: gets an `.asInstanceOf[String]` after erasure
            }
        }
    
      lazy def x(): String =
        if (x$lzy.initialized())
          x$lzy.value() // NOTE: gets an `.asInstanceOf[String]` after erasure
        else
          x$lzycompute();
    
      x()
    }
    
  3. from https://stackoverflow.com/questions/17642275/how-are-lazy-val-class-variables-implemented-in-scala-2-10 by cc-by-sa and MIT license