9

我正在将我的 2.9.* 项目更新到 2.10。我有几个基本类型(角度、长度等)的类,它们似乎是值类型的完美候选者。不幸的是,我使用这些类型的 Java 代码没有编译,我不知道为什么。我已将其简化为一组非常简单的代码。任何建议将不胜感激。

角度类定义(scala)

package com.example.units

class Angle(val radians : Double) extends AnyVal
{
  def degrees = radians * 180.0 / math.Pi
}

object Angle
{
  val Zero = new Angle(0)
}

角度测试用例(痛苦地用 Java 编写)

package com.example.units;

import junit.framework.Assert;
import org.junit.Test;

public class AngleTest
{
    @Test
    public static void TestZero()
    {
        Angle a = Angle.Zero();
        Assert.assertEquals(a.degrees(), 0, 1E-9);

    }

}

当我编译时,我得到这个错误:

AngleTest.java:19 incompatible types
found :double
required: com.example.units.Angle
Angle a = Angle.Zero();

            ^

在我看来,Angle.Zero 好像是作为双精度返回的,而不是角度。我尝试添加 box/unbox 方法,但继续收到相同的错误。再次,任何帮助将不胜感激。

4

1 回答 1

10

Scala 编译器将值类转换为未装箱的类型,从而消除了它们的运行时成本。检查编译的类文件Angle,你会看到:

public static double Zero();

所以从 Java 的角度来看,Angle.Zero 返回一个双精度值;它不知道 Scala 值类的语义。

Angle 自己的方法,例如degrees,被编译为 a) 一个静态扩展方法,它接受未装箱的值 ( double) b) 一个实例方法:

public static double degrees$extension(double);
public double degrees();

这意味着后者仍然可以Angle在 Java 中的实例上调用:

Angle a = new Angle(0);
Assert.assertEquals(a.degrees(), 0, 1E-9);
于 2013-03-31T18:03:31.177 回答