I'm trying to create a structural type in Scala with a method that has a generic return type. For instance, something like:
type Manipulable[T] = Any {
def +(x: Int): T
}
def add[T <: Manipulable[T]](o: T, x: Int) = o + x
// these lines throw Exceptions
add(19.0, 3)
add(3, 3)
add(42L, 3)
Scala's structural types are set scoped to AnyRef
by default, so to use the value types (Java's primitives), we prepend the Any
before the type definition. Structural types can take type parameters, as seen above, but those type parameters cannot then be used as the types of any method value parameters. (You could have x: => T
, but not x: T
.)
When trying to use add()
on a Manipulable[Double]
or Manipulable[Int]
(etc.), though, we get a Java NoSuchMethodException
. Note that this only happens with methods with purely generic return types. The following structural type, for instance, works fine:
type Manipulable[T] = Any {
def getClass (): Class[T] // Class[_] also works
def toString() : String
}
def gc[T <: Manipulable[T]](o: T): Class[T] = o.getClass()
gc(19.0) // Class[Double] = class java.lang.Double
gc(3) // Class[Int] = class java.lang.Integer
gc(42L) // Class[Long] = class java.lang.Long
def str[T <: Manipulable[T]](o: T): String = o.toString()
str(19.0) // String = 19.0
str(3) // String = 3
str(42L) // String = 42
I'm guessing this is an issue with value types in Scala, because reference types seem fine:
type Manipulable[T] = Any {
def substring(x: Int) : T
}
def ss[T <: Manipulable[T]](o: T, x: Int) = o.substring(x)
ss("hello, world", 7) // prints "world"
Any ideas?
Aucun commentaire:
Enregistrer un commentaire