以下代码如何编译:
这里实际上发生了什么?
import scala.concurrent.duration._
val time = 20 seconds
这里实际上发生了什么?
有几个要点需要注意。
首先,Scala允许在许多方法调用中省略点号和括号,因此20秒
等同于20.seconds()
*。
其次,应用了“隐式转换”。由于20
是一个Int
类型且Int
没有seconds
方法,编译器会搜索一个隐式转换,以取一个Int
并返回一个具有seconds
方法的对象,搜索的范围受限于您的方法调用作用域。
已经将DurationInt导入到您的作用域中。由于DurationInt
是一个具有Int
参数的隐式类,它的构造函数定义了一个Int => DurationInt
的隐式转换。由于DurationInt
具有seconds
方法,因此它满足所有搜索条件。因此,编译器会将您的调用重写为new DurationInt(20).seconds
**。
*这里用得不是很准确。实际上,20.seconds()
无效,因为seconds
方法没有参数列表,因此必须在方法调用中省略括号。
**实际上,这并不完全正确,因为DurationInt
是一个值类,所以编译器会尽可能避免包装整数。
import scala.concurrent.duration._
可以解析出20秒
,但实际上导入DurationConversions
特质却不行呢?编辑: 我刚意识到他们实际上导入的是 DurationInt
。我猜这是因为你不能导入特质本身?只能导入特质的具体实现? - franklin
new DurationInt(20).seconds()
更易读,只要你知道它是如何实现的) - William Billingsleyseconds
方法是没有括号定义的,因此在使用括号调用它是错误的。 - Frank S. Thomas20.seconds()
,只是编译器会将调用翻译成这种方式。值得指出的是,如果相应的方法没有参数列表,Scala 要求你省略括号,就像这个例子一样。 - Aaron Novstrup