首页 文章

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

提问于
浏览
10

定义空特性测试:

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

这是正常的编译器行为吗?

1 回答

  • 5

    你've bumped into one of the cases where 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)
    

    或在调用case类时使用强制转换:

    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)
    

相关问题