[英]scala lower and upper bounds
class Queue[+T](
private val leading: List[T],
private val trailing: List[T]
) {
def append[U >: T](x: U) =
new Queue[U](leading, x :: trailing) // ...
}
class Fruit
class oranges extends Fruit
class apple extends Fruit
class diffAppale
val q1: Queue[Fruit] = new Queue[apple](List(new apple), List())
//> q1 : Test.Queue[Test.Fruit] = Test$Queue@30c7da1e
q1.append(new Fruit)
//> res0: Test.Queue[Test.Fruit] = Test$Queue@506e6d5e
q1.append(new oranges)
//> res1: Test.Queue[Test.Fruit] = Test$Queue@96532d6
q1.append(new diffAppale) // i want to restrict this
//> res2: Test.Queue[Object] = Test$Queue@3796751b
在这里,我可以将任何对象添加到附加函数中,我可以看到结果类型被降级为最低公分母
但我想有与 java 相同的行为,比如 def append[? super T](x: U) // 这里的 append 函数将获取 T 的所有超类型对象,我如何在 Scala 中实现类似的对象(实现 super 并扩展像 java 这样的泛型)
我不明白你为什么要限制这个,或者为什么返回一个更通用的新不可变对象会给你带来问题。
但是,如果您不想要这种差异,只需删除所有差异注释:
class Queue[A](leading: List[A], trailing: List[A]) {
def append(x: A) = new Queue[A](leading, x :: trailing) // ...
}
class Fruit
class Orange extends Fruit
class Apple extends Fruit
class NotFruit
val q1: Queue[Fruit] = new Queue(List(new Apple), Nil)
val q2 = q1.append(new Fruit) // ok
val q3 = q2.append(new Orange) // ok
q1.append(new NotFruit) // error - found NotFruit, required Fruit
至于问题:
append 函数将获取所有属于 T 超类型的对象
这就是您的原始代码已经做到的。 请注意, Any
是所有类型的超类型。 由于参数是在协变位置时,它总是能够传递值与子类型的Any
用于预期类型的参数Any
。 这就是生活:) Scala 只是感觉与 Java 不同,因为它是围绕声明站点差异构建的,而不是使用站点差异(可以说是比 Java 的泛型更好的决定)。
如果你想要进一步的约束,你可以要求一个证据参数,比如
def append[B >: A](x: B)(implicit ev: B <:< Seedless): Queue[B]
或者设置一个上限(由于A
的方差,这不能与A
相同):
def append[B >: A <: Fruit](x: B): Queue[B]
但是:恕我直言,这真的没有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.