【发布时间】:2013-02-12 19:32:21
【问题描述】:
以下如何编译:
import scala.concurrent.duration._
val time = 20 seconds
这里到底发生了什么?
【问题讨论】:
以下如何编译:
import scala.concurrent.duration._
val time = 20 seconds
这里到底发生了什么?
【问题讨论】:
发生了一些事情。
首先,Scala 允许在许多方法调用中省略点和括号,因此20 seconds 等价于20.seconds()*。
其次,应用“隐式转换”。由于20 是Int 并且Int 没有seconds 方法,因此编译器会搜索采用Int 并返回确实有 seconds 的隐式转换方法,搜索受方法调用范围的限制。
您已将DurationInt 导入您的作用域。由于DurationInt 是一个带有Int 参数的隐式类,它的构造函数定义了一个隐式Int => DurationInt 转换。 DurationInt 有一个 seconds 方法,因此它满足所有搜索条件。因此,编译器将您的调用重写为new DurationInt(20).seconds**。
*我的意思是松散的。 20.seconds() 实际上是无效的,因为seconds 方法没有参数列表,因此在方法调用中必须省略括号。
**实际上,这并不完全正确,因为DurationInt 是一个值类,因此编译器会尽可能避免包装整数。
【讨论】:
new DurationInt(20).seconds() 更易读,只要你知道它是如何做到的)
seconds方法是不带括号定义的,所以带括号调用是错误的。
20.seconds(),只是编译器正在以这种方式翻译调用。值得指出的是,如果对应的方法没有参数列表,则 Scala 要求省略括号,如本例所示。
那里发生的“魔法”称为“隐式转换”。您正在导入隐式转换,其中一些处理 Int(和 Double)到 Duration 之间的转换。这就是你正在处理的问题。
【讨论】:
import scala.concurrent.duration._ 会解析 20 seconds 但实际上导入 DurationConversions 特征却没有? 编辑:刚刚意识到他们实际导入的是DurationInt。我猜这是因为您无法导入实际的特征?只有 Trait 的具体实现?