0

我是 Scala 的新手,在使用简单的通用 for 循环声明时遇到了问题,其中我的类的一个实例 FinSet[T] 与我的另一个 FinSet[T] 实例“联合”。这是我目前对 U(Union 的缩写)的实现:

def U(other:FinSet[T]) = {
  var otherList = other.toList
  for(otherElem <- 0 until otherList.length){
    this.+(otherElem)
  }
  this
}

尝试编译时,收到此错误。

error: type mismatch:
found:   : otherElem.type (with underlying type Int)
required : T
    this.+(otherElem)

这是在类 ListSet[T] 中,它是抽象类 FinSet[T] 的扩展。两者都显示在这里:

abstract class FinSet[T] protected () {
 /* returns a list consisting of the set's elements */
  def toList:List[T]

  /* given a value x, it retuns a new set consisting of x
     and all the elemens of this (set)
  */
  def +(x:T):FinSet[T]

  /* given a set other, it returns the union of this and other,
     i.e., a new set consisting of all the elements of this and
     all the elements of other
  */
      def U(other:FinSet[T]):FinSet[T]  

  /* given a set other, it returns the intersection of this and other,
     i.e., a new set consisting of all the elements that occur both
     in this and in other
  */
  def ^(other:FinSet[T]):FinSet[T]

  /* given a set other, it returns the difference of this and other,
     i.e., a new set consisting of all the elements of this that
     do not occur in other
  */
  def \(other:FinSet[T]):FinSet[T]

  /* given a value x, it retuns true if and only if x is an element of this 
  */
  def contains(x: T):Boolean

  /* given a set other, it returns true if and only if this is included
     in other, i.e., iff every element of this is an element of other
  */
  def <=(other:FinSet[T]):Boolean = 
    false // replace this line with your implementation


  override def toString = "{" ++ (toList mkString ", ") ++ "}"

  // overrides the default definition of == (an alias of equals)
  override def equals(other:Any):Boolean = other match {
    // if other is an instance of FinSet[T] then ...
    case o:FinSet[T] => 
      // it is equal to this iff it includes and is included in this
      (this <= o) && (o <= this)
    case _ => false
  }
}

在这里,ListSet:

class ListSet[T] private (l: List[T]) extends FinSet[T] {
  def this() = this(Nil)

  // invariant: elems is a list with no repetitions
  //            storing all of the set's elements 
  private val elems = l

  private def add(x:T, l:List[T]):List[T] = l match {
    case Nil => x :: Nil
    case y :: t => if (x == y) l else y :: add(x, t)
  }

  val toList = 
    elems

  def +(x: T) = 
    this.toList.+(x)

  def U(other:FinSet[T]) = {
    var otherList = other.toList
    for(otherElem <- 0 until otherList.length){
      this.+(otherElem)
    }
    this
  }

  def ^(other:FinSet[T]) = 
    this

  def \(other:FinSet[T]) = 
    this

  def contains(x:T) = 
    false
}

我在这里遗漏了一些明显的东西吗?

4

1 回答 1

1

在您的 for 循环中,您将Ints 分配给otherElemx until y产生 a ,这有效地为您提供了从up 到sRange[Int]的迭代),而不是 otherList 的成员。你想要的是这样的:Intxy

  def U(other:FinSet[T]) = {
    for(otherElem <- other.toList){
      this.+(otherElem)
    }
    this
  }

编辑

很好奇,鉴于您对 FinSet 和 ListSet 的定义(直到给出初步答案后我才看到),您应该对上述代码有一些其他问题(+返回 a List,而不是 FinSet,并且您没有捕获在任何地方使用的结果+,所以你的最终返回值this应该只是返回集合的原始值——除非你没有使用标准的 Scala 不可变 List 类?如果没有,你在这里使用哪个类?)。如果您使用的是标准 Scala 不可变 List 类,那么可以考虑以下替代方案:

def U(other:FinSet[T]) = new ListSet((this.toList ++ other.toList).distinct)

一般而言,生成您感兴趣的数据结构的可变版本看起来有点麻烦。我强烈建议您研究不可变数据结构以及如何使用它们 - 它们更好更安全一旦你了解了这些原则,就可以使用。

于 2013-10-08T23:31:04.023 回答