Scala,Long,Int等中的类型

时间:2011-12-20 17:47:42

标签: scala

请输入。

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

世界上到底发生了什么?我一直在跳伞,我必须说这是我见过的最危险的事情。没有编译器检查这个?显然,如果我用150代替一个不同的变量。

*编辑*

这是让我担心的实际代码。

val oneDay = 86400000
val days150 = oneDay * 150

days150 = 75098112

除了我自己以外,这不是斯卡拉的错,也不是任何人的错。让我担心。

2 个答案:

答案 0 :(得分:15)

没有Scala特定的内容。这只是分配的目标类型与执行操作(在这种情况下是乘法)的类型无关的问题。

例如,在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
    }
}

这里的unchecked部分是因为C#编译器足够智能以实现操作溢出,但仅仅因为两个操作数都是常量。如果任一操作数都是变量,那么没有unchecked就可以了。

同样在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
    }
}

答案 1 :(得分:0)

显然没有隐含的演员阵容。我想象jvm 86400000 * 150被视为int * int。然后将其计算分配给任何不需要的变量类型。因此,正确的做法是确保至少有一个数字或变量被转换为long类型86400000 * 150.toLong。 jvm似乎默认为较大的类型。

不过,我相信对scala结束的溢出检查只会削弱性能。因此省略自动类型转换会带来风险,但可以提供更好的性能。你必须要小心......,如果你来自c / c ++备份,这应该是第二天性。