简体   繁体   English

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

[英]Scala implicit conversion on call-by-name parameter works differently depending on the function is overloaded or not

Let's see the code below: 我们来看下面的代码:

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
}

This code does not print anything, because the block contains println("Hello") treated as => Int and it is converted to Foo by int2Foo . 此代码不会打印任何内容,因为该块包含被视为=> Int println("Hello")并且它被int2Foo转换为Foo But the surprising thing is happen if we omit the overloaded function bar(foo: Boolean) 但是如果我们省略重载的函数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
}

This prints Hello because it evaluates the block, and only the last statement, 64 in this case, is treated as a call-by-name parameter. 这将打印Hello因为它会对块进行求值,并且只有最后一个语句(在本例中为64被视为按名称调用参数。 I cannot understand what kind of rationale exists behind of this difference. 我无法理解这种差异背后存在什么样的理由。

I think the Scala specification is ambiguous about how implicit views should be applied here. 我认为Scala规范在如何应用隐式视图方面不明确。 In other words, both of the following interpretations of the statement conform to the spec: 换句话说,该陈述的以下两种解释都符合规范:

bar { println("Hello"); int2Foo(64) }
bar { int2Foo({ println("Hello"); 64 }) }

Of course, it is extremely counterintuitive for an unrelated overload to affect this behavior. 当然,对于不相关的重载会影响这种行为,这是非常违反直觉的。 It seems to me that the behavior, although ambiguous, should at least be consistent. 在我看来,这种行为虽然含糊不清,但至少应该是一致的。 This must be an implementation detail of the compiler interactions between overload resolution, by-name parameters, and implicit views. 这必须是重载解析,按名称参数和隐式视图之间的编译器交互的实现细节。 I have filed SI-9386 to address the issue. 我已经提交了SI-9386来解决这个问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM