Scala、Long、Int 等中的类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8579659/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Types in Scala, Long, Int, etc.
提问by Drew H
Please type this in.
请输入这个。
scala> 86400000 * 150
res0: Int = 75098112
scala> val i : Long = 86400000 * 150
i: Long = 75098112
val i = 86400000 * 150.asInstanceOf[Long]
i: Long = 12960000000
val i = 86400000 * 150L
i: Long = 12960000000
What in the world is going on here? I've been skydiving and I must say that this is the most dangerous thing I've ever seen. No compiler check for this? Obviously if I was substituting 150 for a variable that's different.
这到底是怎么回事?我一直在跳伞,我必须说这是我见过的最危险的事情。没有编译器检查这个?显然,如果我用 150 代替一个不同的变量。
*EDIT*
*编辑*
This was the actual code that got me worried.
这是让我担心的实际代码。
val oneDay = 86400000
val days150 = oneDay * 150
days150 = 75098112
This was not Scala's fault or anyones fault except my own. Just got me worried.
这不是 Scala 的错,也不是我自己的错。只是让我担心。
采纳答案by Jon Skeet
There's nothing Scala-specific about this. It's just a matter of the target type of the assignment being irrelevant to the type in which an operation (multiplication in this case) is performed.
对此没有任何特定于 Scala 的内容。只是赋值的目标类型与执行操作(在这种情况下为乘法)的类型无关。
For example, in C#:
例如,在 C# 中:
using System;
class Program
{
static void Main(string[] args)
{
int a = unchecked(86400000 * 150);
long b = unchecked(86400000 * 150);
long c = 86400000 * (long) 150;
long d = 86400000 * 150L;
Console.WriteLine(a); // 75098112
Console.WriteLine(b); // 75098112
Console.WriteLine(c); // 12960000000
Console.WriteLine(d); // 12960000000
}
}
The uncheckedpart here is because the C# compiler is smart enough to realize that the operation overflows, but only because both operands are constants. If either operand had been a variable, it would have been fine without unchecked.
unchecked这里的部分是因为 C# 编译器足够聪明,可以意识到操作溢出,但这仅仅是因为两个操作数都是常量。如果任一操作数是变量,则没有unchecked.
Likewise in Java:
同样在 Java 中:
public class Program
{
public static void main(String[] args)
{
int a = 86400000 * 150;
long b = 86400000 * 150;
long c = 86400000 * (long) 150;
long d = 86400000 * 150L;
System.out.println(a); // 75098112
System.out.println(b); // 75098112
System.out.println(c); // 12960000000
System.out.println(d); // 12960000000
}
}
回答by Jon Skeet
It's obvious there is no implicit casting going on. 86400000 * 150is viewed as int * intby I imagine the jvm. It's calculated then assigned to whatever variable type u desire which makes no difference. So the correct thing to do is make sure at least one of numbers or variables get casted as a long type, 86400000 * 150.toLong. The jvm appears to default to the larger type.
很明显,没有进行隐式转换。86400000 * 150被int * int我想象的 jvm视为。它被计算然后分配给你想要的任何变量类型,这没有区别。所以正确的做法是确保至少有一个数字或变量被转换为长类型,86400000 * 150.toLong. jvm 似乎默认为较大的类型。
Btw, I believe an overflow check on scala's end would only cripple performance. So the omission of automatic type conversion introduces risk but allows for better performance. You just have to be careful ..., which should be second nature if you come from a c/c++ backup.
顺便说一句,我相信对 scala 的溢出检查只会削弱性能。因此,省略自动类型转换会带来风险,但可以提高性能。你只需要小心......,如果你来自 ac/c++ 备份,这应该是第二天性。

