Reputation: 13
Please consider the following trivial example:
class C[P](val list: Seq[P]){
def print(e: P){
println(e)
}
}
object Test{
def g[P](c: C[P]) = {
c.print(c.list(0))
}
def f(i: Int): C[_] = {
i match {
case 1 => new C(Seq(1, 2, 3))
case _ => new C(Seq("A", "B", "C"))
}
}
def main(args: Array[String]): Unit = {
val c = f(1)
g(c) // works
c.print(c.list(0)) // does not work
}
}
My question is, in the main function, why the first call compiles, but the second gives "type mismatch" error.
Is there any other (better) way to do what is intended here?
Edit 1:
According to the answer by @chengpohi, I can change the type of the returned value of f
to C[Any]
, but this generally may not work. For example, if we change the code to
class B[P]
class BInt extends B[Int]
class BString extends B[String]
class C[P](val list: Seq[P], val obj: B[P]) {
def print(e: P) {
println(e)
}
}
object Test {
def g[P](c: C[P]) = {
c.print(c.list(0))
}
def f(i: Int): C[_] = {
i match {
case 1 => new C(Seq(1), new BInt)
case _ => new C(Seq("String"), new BString)
}
}
def main(args: Array[String]): Unit = {
val c = f(1)
g(c) // works
c.print(c.list(0)) // does not work
}
}
I cannot change the return type of f
to C[Any]
anymore ("type mismatch").
Upvotes: 1
Views: 224
Reputation: 170919
You can use type variable patterns to give a name to the type parameter:
f(1) match {
case c: C[a] => c.print(c.list(0))
}
Upvotes: 0
Reputation: 14227
def f(i: Int): C[Any] = {
i match {
case 1 => new C(Seq(1, 2, 3))
case _ => new C(Seq("A", "B", "C"))
}
}
Try to set the f
method return type: C[Any]
from C[_]
, for typeC[_]
, the compiler will translate C[_]
to C<?>
.
for:
def g[P](c: C[P]) = {
c.print(c.list(0))
}
this method works, this is caused by that we have bound P
type in this method g
, so the compiler can infer this generic P
(Object
type).
but in main method:
c.print(c.list(0))
There is no type context for c, and c's type is C[_]
, but c.list
's type is Seq[Any]
, and for the Generic Type P
in the c.print
will be thought as _$1
type. so the type mismatch
compile error throwed.
Upvotes: 1