隐式转换多个级别,为什么int要自动工作?

Rob*_*oll 9 scala

我一直认为在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的隐式转换有效.有人可以解释原因吗?谢谢

Pau*_*per 7

它通过一种不同的机制发生,这种机制对于数字类型是唯一的,称为数字扩展.

SLS 6.26.1价值转换说:

以下五个隐式转换可以应用于表达式e,该表达式具有某些值类型T并且使用某种预期类型pt进行类型检查.

静态重载分辨率

输入实例化

数字扩展

数字文字缩小

价值丢弃

查看应用程序

动态成员选择

(好吧,这超过五个......不知道为什么:)

感兴趣的是数字扩展:

如果Ë具有一个原始数目型弱符合于期望的类型,它被加宽使用的数字转换方法之一的预期的类型toShort,toChar,toInt,toLong,toFloat,toDouble定义在这里.

3.5.16弱一致性

在某些情况下,Scala使用更一般的一致性关系.类型S弱类型符合类型T,写入S <:wT,如果S <:T或S和T都是原始数字类型,并且S在下面的顺序中在T之前.

Byte  <:w Short
Short <:w Int
Char  <:w Int
Int   <:w Long
Long  <:w Float
Float <:w Double
Run Code Online (Sandbox Code Playgroud)

因此println(i.total)成为println(i.total.toFloat)Int <:w <: Long <: Float.

Java(以及C#和许多其他语言)都有数字扩展,Scala决定保留它.

请注意,反向不起作用:a 不能通过这种方式Float隐式转换Int,因为幅度可能会丢失; 这不是"扩大".

-Ywarn-numeric-widen发生这种情况时,您可以添加并收到警告.