Scala类型和F有界类型
我正在学习Scala中的F-bound类型,我遇到了一种情况,我不知道哪里出了问题 我做了三个测试,代码如下:Scala类型和F有界类型,scala,f-bounded-polymorphism,Scala,F Bounded Polymorphism,我正在学习Scala中的F-bound类型,我遇到了一种情况,我不知道哪里出了问题 我做了三个测试,代码如下: import scala.collection.mutable def test1() = { trait Abstract { type ThisType <: Abstract def deepCopy(): ThisType } case class Concrete1(a: Int) extends Abstract { over
import scala.collection.mutable
def test1() = {
trait Abstract {
type ThisType <: Abstract
def deepCopy(): ThisType
}
case class Concrete1(a: Int) extends Abstract {
override type ThisType = Concrete1
override def deepCopy(): ThisType = this.copy()
}
case class Concrete2(a: Int) extends Abstract {
override type ThisType = Concrete2
override def deepCopy(): ThisType = this.copy()
}
val set = new mutable.HashSet[Abstract]()
set ++= List(Concrete1(1), Concrete2(2))
val set2: mutable.Set[Abstract] = set.map(_.deepCopy())
}
def test2() = {
trait Abstract {
type ThisType
def deepCopy(): ThisType
}
case class Concrete1(a: Int) extends Abstract {
override type ThisType = Concrete1
override def deepCopy(): ThisType = this.copy()
}
case class Concrete2(a: Int) extends Abstract {
override type ThisType = Concrete2
override def deepCopy(): ThisType = this.copy()
}
val set = new mutable.HashSet[Abstract]()
set ++= List(Concrete1(1), Concrete2(2))
val set2: mutable.Set[Abstract] = set.map(_.deepCopy())
}
def test3() = {
trait Abstract[T <: Abstract[T]] {
def deepCopy(): T
}
case class Concrete1(a: Int) extends Abstract[Concrete1] {
override def deepCopy(): Concrete1 = this.copy()
}
case class Concrete2(a: Int) extends Abstract[Concrete2] {
override def deepCopy(): Concrete2 = this.copy()
}
val set = new mutable.HashSet[Abstract[_]]()
set ++= List(Concrete1(1), Concrete2(2))
val set2: mutable.Set[Abstract[_]] = set.map(_.deepCopy())
}
我不明白为什么在本例中test2 AbstractThisType与Abstract的类型不同,而在test1中则不同。它是否与路径依赖类型有关?如果是,原因是什么
在test3中,我尝试执行与test1中相同的de,但对于类型参数,此编译器在val set2行抛出一个错误:mutable.Set[Abstract[\u]]=Set.map\uUdeepcopy,表示:
它与通配符有关,但我不知道如何在没有通配符的情况下声明此类类型。这里有一个版本,显示了我解释中的一些部分 因此,由于缺少边界,2 scalac中的问题无法证明Abstract是typemeber的常见超类型。请注意,此类型可以是Int,它实际上不是抽象的子类型,因此不符合集合[Abstract]中的条件
在3中的问题是抽象[u]是一个存在式,它的工作方式与此不同,因此您可以插入一个常见的超类型,如图所示 如果def deepCopy:Abstract[T],test3将编译。不需要进行其他更改,但需要注意的是,如果没有自类型self:T=>您将无法获得F-有界多态性的安全保证。@jwvh为什么?如果没有自类型限制,编译器将允许类Concrete2a:Int扩展抽象[Concrete1]{..,这通常不是您想要的。
Error:(53, 45) type mismatch;
found : scala.collection.mutable.HashSet[Abstract#ThisType]
required: scala.collection.mutable.Set[Abstract]
val set2: mutable.Set[Abstract] = set.map(_.deepCopy())
^
Error:(78, 48) type mismatch;
found : scala.collection.mutable.HashSet[Any]
required: scala.collection.mutable.Set[Abstract[_]]
Note: Any >: Abstract[_], but trait Set is invariant in type A.
You may wish to investigate a wildcard type such as `_ >: Abstract[_]`. (SLS 3.2.10)
val set2: mutable.Set[Abstract[_]] = set.map(_.deepCopy())
^
Error:(140, 45) type mismatch;
found : scala.collection.mutable.HashSet[Abstract#ThisType]
required: scala.collection.mutable.Set[Abstract]
val set2: mutable.Set[Abstract] = set.map(_.deepCopy())
^
Error:(166, 48) type mismatch;
found : scala.collection.mutable.HashSet[Any]
required: scala.collection.mutable.Set[Abstract[_]]
Note: Any >: Abstract[_], but trait Set is invariant in type A.
You may wish to investigate a wildcard type such as `_ >: Abstract[_]`. (SLS 3.2.10)
val set2: mutable.Set[Abstract[_]] = set.map(_.deepCopy())
^