2013-11-20 7 views
9

leer Merkmal Test definiert:Fall Klasse Begleitobjekt Generierungsfehler für Verbindungstyp

trait Test 

was in Verbindung Typ verwendet:

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

und Fall-Klasse mit dem Parameter des Verbindungstypen (wie Unboxed Tagged Typ):

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`. 

Aber es perfekt für sich arbeiten:

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

Und kein Problem mit Methodendefinition:

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

Scala Version 2.10.3

Ist es normal, Compiler Verhalten?

+7

Dies ist ein [bekanntes Problem] (https://issues.scala-lang.org/browse/SI-5183). –

Antwort

5

Sie sind in einen der Fälle geraten, in denen Scalas Versuch, Primitive und Objekte zu vereinheitlichen, zusammenbricht. Da Int in Scala den Java-Primitivtyp int darstellt, kann es keine eingefügten Merkmale enthalten. Wenn asInstanceOf tun, Autoboxen der Scala-Compiler die Int in eine 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 

jedoch Autoboxing passiert nicht, wenn Typen deklarieren, so dass Sie es von Hand zu tun haben:

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

Aber dann der Compiler Typprüfer AutoBox nicht vor die Typen Überprüfung:

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

so würden Sie Ihre Variable alserklären müssen:

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

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

oder eine Besetzung verwenden, wenn der Fall-Klasse aufrufen:

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) 
Verwandte Themen