2012-10-22 18 views
5

App'u genişleten nesnelere biraz da olsa bir davranışla karşılaştım.Uygulamayı genişleten nesneleri yüklerken scala'da ne oluyor?

scala> object A extends App {val x = "I am null"} 
defined module A 

scala> object B {val x = "I am a string"} 
defined module B 

scala> A.x 
res0: java.lang.String = null 

scala> B.x 
res1: java.lang.String = I am a string 

de bu biraz garip ... ama tuhaflaşıyor: Aşağıdaki Çoğaltma bir göz komutları alır. i sonra bu yüzden gerçek lazy val çalıştı ... Bir object içinde vals bazı tembel değerlendirme içine gitmek düşündüm:

scala> object C extends App {lazy val x = "What am I?"} 
defined module C 

scala> C.x 
res2: java.lang.String = What am I? 

yüzden burada neler? Normal bir vali null değeri niçin olur?
lazy val'u kullanırken neden bu davranış değişiyor?
ve App özelliğiyle bu kadar özel olan şey, normal değerlerin derecelendirilmemesini sağlıyor mu?

cevap

9

Uygulama, DelayedInit özelliğinin kapsamını genişletir. Yani tüm ifadeler ve tüm değer tanımları delayedInit yöntemine taşınır. Lazy val, yönteme derlendiği için işe yarıyor. Örneğin

Eğer bu sınıfı koda ise:

class TestApp extends App{ 
    val test = "I am null" 
    lazy val testLazy ="I am a string" 
} 

Sen tembel yöntemle 'ile sınıfını alacak:

public String testLazy() 
{ 
    if((bitmap$0 & 1) == 0) 
     synchronized(this) 
     { 
      if((bitmap$0 & 1) == 0) 
      { 
       testLazy = "I am a string"; 
       bitmap$0 = bitmap$0 | 1; 
      } 
      BoxedUnit _tmp = BoxedUnit.UNIT; 
     } 
    return testLazy; 
} 

ve delayedInit yöntemi delayedInit.body iç sınıf içinde:

public final class delayedInit.body extends AbstractFunction0 
     implements ScalaObject 
    { 

     public final Object apply() 
     { 
      $outer.test_$eq("I am null"); 
      return BoxedUnit.UNIT; 
     } 

     private final TestApp $outer; 
.... 

Öyleyse "ben null" değeri test alanına yalnızca d elayedInit denir.

İlgili konular