复合类型的案例类伴随对象生成错误

时间:2013-11-20 11:28:01

标签: scala case-class compound-type

定义空特性测试:

trait Test

复合型中使用的是什么:

scala> val a : Int with Test = 10.asInstanceOf[Int with Test]
a: Int with Test = 10

和带有复合类型参数的case类(如Unboxed Tagged Type):

scala> case class Foo(a: Int with Test)
error: type mismatch;
 found   : Double
 required: AnyRef
Note: an implicit exists from scala.Double => java.lang.Double, but
methods inherited from Object are rendered ambiguous.  This is to avoid
a blanket implicit which would convert any scala.Double to any AnyRef.
You may wish to use a type ascription: `x: java.lang.Double`.

但它完全适用于:

scala> case class Foo(a: List[Int] with Test)
defined class Foo

方法定义没问题:

scala> def foo(a: Int with Test) = ???
foo: (a: Int with Test)Nothing

Scala版 2.10.3

编译器行为是否正常?

2 个答案:

答案 0 :(得分:5)

你遇到了Scala尝试统一原语和对象的情况之一。由于Scala中的Int表示Java基元类型int,因此不能将任何特征混合到其中。在执行asInstanceOf时,Scala编译器将Int自动装箱到java.lang.Integer

scala> val a: Int with Test = 10.asInstanceOf[Int with Test] 
a: Int with Test = 10

scala> a.getClass
res1: Class[_ <: Int] = class java.lang.Integer

但是,在声明类型时不会发生自动装箱,因此您必须手动执行:

scala> case class Foo(x: Integer with Test)
defined class Foo

但是在检查类型之前,编译器类型检查器不会自动装箱:

scala> Foo(a)
<console>:12: error: type mismatch;
 found   : Int with Test
 required: Integer with Test
              Foo(a)
                  ^

因此,您必须将变量声明为Integer with Test

scala> val a: Integer with Test = 10.asInstanceOf[Integer with Test]
a: Integer with Test = 10

scala> Foo(a)
res3: Foo = Foo(10)

或在调用案例类时使用演员:

val a : Int with Test = 10.asInstanceOf[Int with Test]
scala> a: Int with Test = 10

scala> Foo(a.asInstanceOf[Integer with Test])
res0: Foo = Foo(10)

答案 1 :(得分:2)

@Travis Brown所说,这是已知的issue,已在scala 2.11.7中修复。

在ammonite Repl 2.0.4(scala 2.12.10 java 1.8.0_242)下运行

@case class Foo(a: Int with Test)
a: Int with Test = 10