繁体   English   中英

标量下限和上限

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM