Scala 如何将 Int 转换为 Double?
Posted
技术标签:
【中文标题】Scala 如何将 Int 转换为 Double?【英文标题】:How does Scala convert Int to Double? 【发布时间】:2018-08-16 05:25:41 【问题描述】:val d: Double = 42
当我尝试通过 intellij 找到隐式转换时,没有任何有趣的事情出现。此外,Int
不是Double
的子类型。那么 Scala 是如何做到的呢?
【问题讨论】:
How do I do casting in Scala?的可能重复 @Stoopkid 从某种意义上说,我的问题与该线程相反:我几乎是在问为什么我不需要需要.toDouble
【参考方案1】:
长话短说:这不是对某些伴随对象的普通隐式转换,数值类型得到特殊处理。
如果我们在这个脚本上运行scala -print
:
val d: Double = 42
我们得到:
package <empty>
object Main extends Object
def main(args: Array[String]): Unit =
new <$anon: Object>();
()
;
def <init>(): Main.type =
Main.super.<init>();
()
;
final class anon$1 extends Object
private[this] val d: Double = _;
<stable> <accessor> private def d(): Double = anon$1.this.d;
def <init>(): <$anon: Object> =
anon$1.super.<init>();
anon$1.this.d = 42.0;
()
在脱糖代码中,我们看到一个双字面 42.0
,但没有调用任何转换
函数(例如来自Predef
)。因此,从Int
到Double
的转换必须不发生
在运行时,但在编译的早期阶段。
section 3.5.3 of the specification
告诉我们Int
弱符合 Double
因为弱符合关系<:w
的传递性:
Int <:w Long <:w Float <:w Double
此外,Section 6.26.1 (Value Conversions)
告诉我们,如果 e
类型为 T
的表达式出现在表达式
类型 pt
是预期的,T
弱符合 pt
。在这种情况下,我们可以应用规则
e = 42
表达式类型T = Int
预期类型pt = Double
因此,42
使用 toDouble
转换为 42.0
。由于它是一个可以在编译时处理的常量,
我们在脱糖代码中看不到toDouble
。但是,如果我们对具有非常数的类似程序进行脱糖
价值
val d: Double = (new scala.util.Random).nextInt(42)
我们得到:
package <empty>
object Main extends Object
def main(args: Array[String]): Unit =
new <$anon: Object>();
()
;
def <init>(): Main.type =
Main.super.<init>();
()
;
final class anon$1 extends Object
private[this] val d: Double = _;
<stable> <accessor> private def d(): Double = anon$1.this.d;
def <init>(): <$anon: Object> =
anon$1.super.<init>();
anon$1.this.d = new scala.util.Random().nextInt(42).toDouble();
()
toDouble
在那里,如指定的那样。
【讨论】:
信息量很大,尤其是关于:弱一致性细节。我对 Int-to-Double 隐式转换在幕后起作用的假设是不正确的。 @LeoC 不过,这是一个合理的假设。我无法自发地发明一个示例,让人们在不查看脱糖代码的情况下实际注意到差异。以上是关于Scala 如何将 Int 转换为 Double?的主要内容,如果未能解决你的问题,请参考以下文章