对call-by-name参数的Scala隐式转换的工作方式不同,具体取决于函数是否过载

poc*_*all 7 scala implicit-conversion callbyname

我们来看下面的代码:

import scala.language.implicitConversions
class Foo
implicit def int2Foo(a: => Int): Foo = new Foo
def bar(foo: Foo) = {}
def bar(foo: Boolean) = {}
bar {
  println("Hello")
  64
}
Run Code Online (Sandbox Code Playgroud)

此代码不显示任何信息,因为该块包含println("Hello")被视为=> Int它转化为Foo通过int2Foo.但是如果省略重载函数,就会发生令人惊讶的事情bar(foo: Boolean)

import scala.language.implicitConversions
class Foo
implicit def int2Foo(a: => Int): Foo = new Foo
def bar(foo: Foo) = {}
bar {
  println("Hello")
  64
}
Run Code Online (Sandbox Code Playgroud)

这会打印,Hello因为它会对块进行求值,64在这种情况下,只有最后一个语句被视为按名称调用参数.我无法理解这种差异背后存在什么样的理由.

Ben*_*ich 1

我认为 Scala 规范对于如何应用隐式视图在这里含糊不清。换句话说,该声明的以下两种解释均符合规范:

bar { println("Hello"); int2Foo(64) }
bar { int2Foo({ println("Hello"); 64 }) }
Run Code Online (Sandbox Code Playgroud)

当然,不相关的过载影响这种行为是极其违反直觉的。在我看来,这种行为虽然模棱两可,但至少应该是一致的。这必须是重载解析、按名称参数和隐式视图之间的编译器交互的实现细节。我已提交SI-9386来解决该问题。