Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala协变型错误_Scala - Fatal编程技术网

Scala协变型错误

Scala协变型错误,scala,Scala,我试图定义一个类 abstract class Sequence[+A] { def append (x: Sequence[A]): Sequence[A] } 进了候机楼 <console>:8: error: covariant type A occurs in contravariant position in type Sequence[A] of value x def append (x: Sequence[A]): Sequence[A

我试图定义一个类

abstract class Sequence[+A] {
    def append (x: Sequence[A]): Sequence[A]
}
进了候机楼

<console>:8: error: covariant type A occurs in contravariant position in type Sequence[A] of value x
           def append (x: Sequence[A]): Sequence[A]
:8:错误:协变类型A出现在值x的类型序列[A]中的逆变位置
def append(x:Sequence[A]):Sequence[A]
为什么这个定义不正确?解决这个问题的最佳方法是什么? 我检查了这个,但没有任何帮助。

这个功能:

abstract class Sequence[+A]{
  def append[B >: A](x: Sequence[B]): Sequence[B]
}

定义协变类型时,不能将其用作输入参数(用于返回类型的逆变类型也会有同样的问题)。解决方法是定义一个新类型(这里是B),它是a的超级类型。

鉴于@vptheron在Scala方面的专业知识,他在解决方案上完全正确。但让我以Scala作家Martin Odersky本人的灵感为例来补充一下“为什么”

通过定义
Sequence[+A]
,你是说如果
B
A
的一个子类型,那么
Sequence[B]
就是
Sequence[A]
的一个子类型

我认为,当你从抽象(没有双关语)中拿出一个具体的例子时,类型的东西会更有意义

让我们创建一个具体的实现:

class IntSequence extends Sequence[Int] {
  override def append(x: Sequence[Int]) = {
    println(math.sqrt(x.head))
    //makes no sense but humor me
  }
}
A
中的协方差意味着因为
Int
Any
的子类型,
Sequence[Int]
Sequence[Any]
的子类型。到目前为止还不错

现在想象一个具体的类
StringSequence
,其定义方式与
IntSequence
类似

那么让我们这样做:

val x:Sequence[Any] = new IntSequence
val ss:Sequence[Any] = new StringSequence
//Let ss be populated somehow
x.append(ss)
第一行当然有效
IntSequence
Sequence[Int]
的一个子类,
Sequence[Int]
Sequence[Any]
协方差的一个子类型

第二行当然有效。出于类似的原因

第三行(注释后的一行)当然有效
Sequence[String]
Sequence[Any]
的子类,因此我可以将
Sequence[String]
附加到
Sequence[Any]

但是当我尝试将这两行放在一起时,我已经说过我可以取我的
序列[String]
的第一个元素的平方根,因为
x
实际上是一个
IntSequence

借用美国电影《阿波罗13号》中的一句话,“休斯顿,我们有个问题。”

这就是为什么会出现这种错误。概括地说,一旦泛型参数作为方法的参数类型出现,包含该方法的类就不能在该类型中是协变的,因为您得到的正是这种奇怪

要解决这个问题,您需要为方法定义中的类型参数设置一个下限。换句话说,方法参数中的类型必须是类定义中协变类型的超类型

或者更简单地说,做@vptheron做的事情


希望有帮助

很好的解释!我在这件事上有点懒:)谢谢!别担心。还有其他人需要你的超级斯卡拉英雄气概。