我一直认为在scala中不可能进行多级隐式转换(除非你定义视图边界:http://docs.scala-lang.org/tutorials/FAQ/context-and-view-bounds.html)
但似乎类型系统存在缺陷或不一致.以下示例(改编自如何在Scala中链接implicits?)
class A(val n: Double){
def total = n + 10
}
object T1{
implicit def toA(n: Double): A = new A(n)
val i : Int = 5
println(i.total) //Why does this work?
println(5.2.total)
}
Run Code Online (Sandbox Code Playgroud)
我真的不明白为什么Int - > Double - > A的隐式转换有效.有人可以解释原因吗?谢谢
它通过一种不同的机制发生,这种机制对于数字类型是唯一的,称为数字扩展.
以下五个隐式转换可以应用于表达式e,该表达式具有某些值类型T并且使用某种预期类型pt进行类型检查.
静态重载分辨率
输入实例化
数字扩展
数字文字缩小
价值丢弃
查看应用程序
动态成员选择
(好吧,这超过五个......不知道为什么:)
感兴趣的是数字扩展:
如果Ë具有一个原始数目型弱符合于期望的类型,它被加宽使用的数字转换方法之一的预期的类型
toShort,toChar,toInt,toLong,toFloat,toDouble定义在这里.
在某些情况下,Scala使用更一般的一致性关系.类型S弱类型符合类型T,写入S <:wT,如果S <:T或S和T都是原始数字类型,并且S在下面的顺序中在T之前.
Run Code Online (Sandbox Code Playgroud)Byte <:w Short Short <:w Int Char <:w Int Int <:w Long Long <:w Float Float <:w Double
因此println(i.total)成为println(i.total.toFloat)因Int <:w <: Long <: Float.
Java(以及C#和许多其他语言)都有数字扩展,Scala决定保留它.
请注意,反向不起作用:a 不能通过这种方式Float隐式转换Int,因为幅度可能会丢失; 这不是"扩大".
-Ywarn-numeric-widen发生这种情况时,您可以添加并收到警告.