2014-12-21 23 views
5

Scala'nın UNTIL, REPEAT kontrol akışını modelleme yeteneği sağladığı söylendi.Neden UNTIL/REPEAT modelinin kodu yeni anahtar kelime gerektiriyor?

// ref: https://gist.github.com/metasim/7503601 
def REPEAT(body: => Unit) = new { 
    def UNTIL(condition: => Boolean): Unit = { 
    body 
    if (condition)() 
    else UNTIL(condition) 
    } 
} 

// test code 
REPEAT { 
    x = x + 1 
} UNTIL (x > 3) 

Neden REPEAT işlevinde new kelime gereklidir: yeteneği okurken

, kodu buldum?

+0

Çünkü 'UNTIL' bir yöntemdir, bir (n istekli) işlevinin adı değildir. –

+0

Sonra, 'yeni {} 'bir nesne oluşturuyor? Bildiğim gibi, yöntem – 1ambda

cevap

3

new { def ...} yapı structural typeAnyRef{def ...} ile yeni bir anonim nesne oluşturur:

scala> val aa = new { def kk = "bb" } 
aa: AnyRef{def kk: String} 

Sizin UNTIL yöntem çünkü "yapısal tipi elemanın yansıtıcı erişim" olarak adlandırılan özelliği erişilebilir ve ayrıca en az bir import scala.language.reflectiveCalls olmalıdır

scala> aa.kk 
<console>:9: warning: reflective access of structural type member method kk should be enabled 
by making the implicit value scala.language.reflectiveCalls visible. 
This can be achieved by adding the import clause 'import scala.language.reflectiveCalls' 
or by setting the compiler option -language:reflectiveCalls. 
See the Scala docs for value scala.language.reflectiveCalls for a discussion 
why the feature should be explicitly enabled. 
       aa.kk 
       ^
res0: String = bb 

Not, bu tanımlamak yerine biraz daha yavaş olduğunu: Scala 2.11.2 yılında SIP 18: Modularizing Language Features sonucu class Repeatable {def UNTIL = ...}, çünkü (JVM için)işleviniz Object (AnyRef) değerini döndürür ve bundan böyle yayınlanacak bir tür yoktur, bu nedenle Scala yansımayı kullanarak UNTIL'u çağırır. Aynı zamanda bazı sentetik sınıflar da sunmamıştır, çünkü yapısal tip herhangi bir mevcut sınıfla (uygun UNTIL yöntemiyle başka herhangi bir sınıf) eşleşebilir.

+0

bir nesnede olmalıdır Teşekkürler! Beklediğimden biraz daha derin. Özetle, ördek tipi nesne (AnyRef) bir anonim (?) Nesneye benziyor. Sınıf gerektirmez, sadece uygulamaya ihtiyaç duyar. Ama bir sorum daha var. ReflectiveCalls almadım bile, kodum işe yarıyor. Sadece scala yorumcusu bu paketi içe aktarmayı gerektirir mi? – 1ambda

+1

Yrw. Nesne kendisi bir sınıf (resmi tip) AnyRef var, ördek-yazarak uygun imza ile gerçek bir tip olmasını sağlar ve yansıma yöntemlerini çağırır. Kodunuz çalışır, ancak yine de bu uyarıyı alırsınız (tam uyarı metni "scala -feature" ile kullanılabilir) – dk14

İlgili konular