我被告知Scala提供了对UNTIL, REPEAT
控制流进行建模的功能。
在研究能力时,我找到了代码:
// 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)
为什么需要new
功能中的REPEAT
关键字?
答案 0 :(得分:3)
new { def ...}
构造使用structural type AnyRef{def ...}
创建一个新的匿名对象:
scala> val aa = new { def kk = "bb" }
aa: AnyRef{def kk: String}
您的UNTIL
方法是可访问的,因为称为"结构类型成员"的反射访问,您还应该有import scala.language.reflectiveCalls
,至少在Scala 2.11.2中SIP 18: Modularizing Language Features的结果:
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
注意,它比定义class Repeatable {def UNTIL = ...}
慢一点,因为(对于JVM)你的REPEAT
函数只返回Object
(AnyRef)并且没有类型从中投射,因此Scala使用反射调用UNTIL
。它也没有引入一些合成类,因为结构类型可以匹配任何现有的类(任何其他类具有适当的UNTIL
方法)。