Scala 为什么建模到/重复的代码需要新的关键字?

Scala 为什么建模到/重复的代码需要新的关键字?,scala,Scala,我听说Scala提供了建模直到重复控制流的功能 在研究该功能时,我发现了以下代码: //ref:https://gist.github.com/metasim/7503601 def重复(主体:=>装置)=新{ def直到(条件=>布尔值):单位={ 身体 如果(条件)() 否则直到(条件) } } //测试代码 重复{ x=x+1 }直到(x>3) 为什么需要REPEAT函数中的new关键字?new{def…}构造使用AnyRef{def…}创建一个新的匿名对象: scala> val

我听说Scala提供了建模
直到重复
控制流的功能

在研究该功能时,我发现了以下代码:

//ref:https://gist.github.com/metasim/7503601
def重复(主体:=>装置)=新{
def直到(条件=>布尔值):单位={
身体
如果(条件)()
否则直到(条件)
}
}
//测试代码
重复{
x=x+1
}直到(x>3)

为什么需要
REPEAT
函数中的
new
关键字?

new{def…}
构造使用
AnyRef{def…}
创建一个新的匿名对象:

scala> val aa = new { def kk = "bb" }
aa: AnyRef{def kk: String}
由于名为“结构类型成员的反射访问”的功能,您的
UNTIL
方法可以访问,并且您还应该至少在scala 2.11.2中具有导入scala.language.reflectiveCalls
,因为:

scala>aa.kk
:9:警告:应启用结构类型构件方法kk的反射访问
通过使隐式值scala.language.reflectiveCalls可见。
这可以通过添加import子句“import scala.language.reflectiveCalls”来实现
或者通过设置编译器选项-language:reflectiveCalls。
请参阅Scala文档中的值Scala.language.reflectiveCalls以了解讨论
为什么应该显式启用该功能。
aa.kk
^
res0:String=bb

请注意,它比定义
类可重复{def UNTIL=…}
要慢一点,因为(对于JVM)您的
REPEAT
函数只返回
对象(AnyRef),并且没有类型可以从它转换,所以Scala使用反射调用
UNTIL
。它也没有引入一些合成类,因为结构类型可以匹配任何现有类(使用适当的
UNTIL
方法的任何其他类)。

因为
UNTIL
是一个方法,而不是(n)函数的名称。然后,
new{}
创建一个对象?正如我所知,方法应该在ObjectThank中!比我想象的要深刻一些。总之,duck类型的对象(AnyRef)看起来像一个匿名(?)对象。它不需要类,只需要实现。但我还有一个问题。即使我没有导入reflectiveCalls,我的代码也能正常工作。只有scala解释器需要导入该包?Yrw。对象本身有一个类(形式类型)AnyRef,duck类型允许它有带有适当签名的实类型,并通过反射调用其方法。您的代码可以工作,但仍然会收到此警告(完整的警告文本可通过“scala-feature”获得)
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