scala - 隐式转换和 null
问题描述
以下代码
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))
}
}
}
没有接受 null 的 int 符号方法
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?
PS。我不是在这里谈论最佳实践。随意将问题视为学术兴趣问题。
解决方案
所以,@AndreyTyukin 说的是对的,机械地我认为还有更多。至于为什么,有两件事正在发生。
Any
implicit
用中的装饰Predef
,请参见以下内容:implicit final class any2stringadd[A] extends AnyVal
如您所见,any2stringadd
负责的是+
,您可以在此处看到签名:
def +(other: String): String
更正:没有implicit conversions
,比那个更简单
- 查看源代码
Predef
并且any2stringadd
确实在起作用的是以下内容
implicit final class any2stringadd[A](private val self: A) extends AnyVal {
def +(other: String): String = String.valueOf(self) + other
}
String.valueOf
of1
将返回一个String
of 1
。在 Java 中(并使用 jshell 验证),String
添加1
到的 anull
将变为1null
.
jshell> "1" + null
$1 ==> "1null"
推荐阅读
- c - 逻辑检查未按预期输出。(数独检查器)C
- python-3.x - 如何创建预签名 URL 以使用 Boto3 从 S3 存储桶下载文件?
- android - 如何理解android中的wifi代码流?
- c# - 为什么我们要在 ConfigureServices 中的 AddJwtBearer 以及在 asp.net 核心中创建新的 JwtSecurityToken 时提供颁发者、受众和密钥
- javascript - Javascript 滚动动画
- python-3.x - KeyError:“[Int64Index([1960, 1961, 1962, 1963, 1964], dtype='int64')] 均不在 [列] 中”
- sql - go-GORM 无法插入值
- javascript - 在 IIS 10 中浏览时未加载图像
- azure - 无法创建 Azure Web App Bot,出现身份验证错误
- python - 此功能的完美 numpy 实现