val d: Double = 42
当我尝试通过intellij找到隐式转换时,没有任何有趣的东西出现。此外,Int
不是Double
的子类型。那么Scala是如何做到的呢?
答案 0 :(得分:12)
长话短说:这不是对某些伴侣对象的普通隐式转换,数值类型得到了特殊处理。
如果我们在此脚本上运行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;
()
}
}
}
在desugared代码中,我们看到了双字面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
因此,使用42.0
将toDouble
转换为toDouble
。因为它是一个可以在编译时处理的常量,
我们在desugared代码中看不到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
并且<!DOCTYPE html>
<html lang="en">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport"></meta>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type"></meta>
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<link href="resource/css/main.css" rel="stylesheet"></link>
<title>My App</title>
</head>
<body>
<form action="${pageContext.request.contextPath}/uploadServlet" method="post" enctype="multipart/form-data">
<input type="text" name="description" />
<input type="file" name="file" />
<input type="submit" name="submit"/>
</form>
<button id="processData" type="button" class="btn btn-primary">ProcessData</button>
<br></br>
<br></br>
<script src="js/mainJs.js"></script>
</body>
</html>
符合规定。