Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.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类型和F有界类型_Scala_F Bounded Polymorphism - Fatal编程技术网

Scala类型和F有界类型

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

我正在学习Scala中的F-bound类型,我遇到了一种情况,我不知道哪里出了问题

我做了三个测试,代码如下:

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())
                                              ^