Reputation: 75
I have a below class which uses covariance annotation and another type parameter for its method to which class type parameter is lower bound
class MyQueue[+T]{
def add[U >: T](arg:U):Unit= {
println("Arg value :"+ arg)
}
}
Given above code, I don't understand why below lines execute successfully. As per my understanding of lower bounds, method "add" should only accept value of type Int or its super-type.
val q1:MyQueue[Int] = new MyQueue[Int]
q1.add("string")
However, it gives expected compilation error (String do not conform to method add's type parameter bounds) if we explicitly specify the type argument as below
q1.add[String]("string")
Upvotes: 2
Views: 543
Reputation: 51703
I'll just add to @MikelSanVicente's answer that if you want q1.add("string")
not to compile you should replace type bound with implicit type constraint
class MyQueue[+T]{
def add[U](arg: U)(implicit ev: T <:< U): Unit= {
println("Arg value :"+ arg)
}
}
val q1: MyQueue[Int] = new MyQueue[Int]
q1.add("string") // doesn't compile
q1.add[String]("string") // doesn't compile
q1.add[Any]("string") // compiles
https://blog.bruchez.name/2015/11/generalized-type-constraints-in-scala.html
Upvotes: 4
Reputation: 3863
String
is not a supertype of Int
but there is a common supertype shared between Int
and String
and that is Any
val q1:MyQueue[Int] = new MyQueue[Int]
q1.add("string")
is equivalent to
val q1:MyQueue[Int] = new MyQueue[Int]
q1.add[Any]("string")
on the other hand, if you explicitly pass String
as the type parameter a compilation error will happen because String
is not a supertype of Int
Upvotes: 5