在以下代码中,隐式转换应用于println(2)行;我愚蠢地期望它适用于整个区块{println(1); println(2)}.我应该如何推断编译器放置隐含的位置?
object Executor { private var runnable: Runnable = _ def setRunnable(runnable: Runnable) { this.runnable = runnable } def execute() { runnable.run() } } object Run extends App { implicit def blockToRunnable(p: ⇒ Any): Runnable = new Runnable { def run() = p } Executor.setRunnable { println(1) println(2) } println("Before execute") Executor.execute() }
解决方法
根据规范,当表达式的类型与期望的类型不匹配时,将应用隐式转换.关键的观察是在键入块时如何线程化预期的类型.
if an expression
e
is of typeT
,and T does not conform to the expression’s expected typept
. In this case an implicit v is searched which is applicable to e and whose result type conforms to pt.
在第6.11节块中,块的最后一个表达式的预期类型定义为
The expected type of the final expression
e
is the expected type of the block.
鉴于此规范,编译器似乎必须采用这种方式.块的预期类型是Runnable,println(2)的预期类型也变为Runnable.
建议:如果您想知道应用了哪些implicits,可以使用适用于Eclipse的Scala IDE 2.1的每晚构建.它可以“突出隐含”.
编辑:我承认,当范围内隐含着一个名字叫做时,这是令人惊讶的.