【发布时间】:2019-03-04 16:52:22
【问题描述】:
以下代码
import scala.language.implicitConversions
object myObj {
implicit def nullToInt(x: Null) = 0
def main(args: Array[String]): Unit = {
val x = 1 + null
val y = 1 + nullToInt(null)
println(x + " " + y)
}
}
给出以下结果
1null 1
我希望两个 val 都是 Int 并且等于 1。
显然第一个 val 是 String 并且等于“1null”。
Xprint:typer显示源代码被翻译成
package <empty> {
import scala.language.implicitConversions;
object myObj extends scala.AnyRef {
def <init>(): myObj.type = {
myObj.super.<init>();
()
};
implicit def nullToInt(x: Null): Int = 0;
def main(args: Array[String]): Unit = {
val x: String = 1.+(null);
val y: Int = 1.+(myObj.this.nullToInt(null));
scala.Predef.println(x.+(" ").+(y))
}
}
}
int 没有接受 null 的符号方法
scala> 10+null
res0: String = 10null
scala> 10*null
<console>:12: error: overloaded method value * with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int
cannot be applied to (Null)
10*null
^
scala> 10-null
<console>:12: error: overloaded method value - with alternatives:
(x: Double)Double <and>
(x: Float)Float <and>
(x: Long)Long <and>
(x: Int)Int <and>
(x: Char)Int <and>
(x: Short)Int <and>
(x: Byte)Int
cannot be applied to (Null)
10-null
^
我假设“1”和“null”都被转换为字符串,而不是应用隐式 nullToInt。有人能解释一下编译器是怎么想出来的吗?使用了什么逻辑/工作流程?
另一个问题是是否有办法启用隐式 nullToInt?
附言。我不是在这里谈论最佳实践。随意将问题视为学术兴趣问题。
【问题讨论】:
-
不是答案,也不是改进问题的建议,而是将
+的奇怪行为与任何其他方法(此处为+++)进行对比的有趣事实:import language.implicitConversions; class I { def +++(i: I) = "I +++ I" }; class S { def +++(a: Any) = "S +++ Any" }; class N; implicit def n2i(n: N): I = new I; implicit def i2s(i: I): S = new S; println((new I) +++ (new N));这转换N到I并调用I的+++,而不是S的调用。我不知道为什么它与+相反。
标签: scala operators string-concatenation