2

标记为家庭作业。在尝试实现一个类时,我在面向对象的世界中遇到了麻烦。

我正在实现各种功能来对列表采取行动,我用来模拟一个集合。例如,我不太担心如何找到联合的逻辑,但实际上只是结构。

例如:

abstract class parentSet[T] protected () {

    def union(other:parentSet[T]):parentSet[T]

}

现在我想要一个扩展 parentSet 的新类:

class childSet[T] private (l: List[T]) extends parentSet[T] {
    def this() = this(List())
    private val elems = l
    val toList = List[T] => new List(l)

    def union(other:parentSet[T]):childSet[T] = {
        for (i <- this.toList) {
            if (other contains i) {}
            else {l :: i}
        }
        return l
    }
}

编译时,我收到错误,例如在 def union 中找不到类型 childSet,也没有类型 T 来保持它的参数化。另外,我认为我的 toList 不正确,因为它抱怨它不是对象的成员;仅举几例。

我的语法哪里错了?

编辑

现在我已经弄清楚了:

  def U(other:parentSet[T]):childSet[T] = {
    var w = other.toList
    for (i <- this.toList) {
        if (!(other contains i)) {w = i::w}
    }
    return new childSet(w)

}

现在,我正在尝试对 map 执行相同的操作,这就是我正在处理/使用的:

def U(other:parentSet[T]):MapSet[T] =  {
    var a = Map[T,Unit]
    for (i <- this.toList) {
        if (!(other contains i)) {a = a + (i->())}
    }
    return new MapSet(elems + (a->()))
  }

我仍然想使用 toList 使它易于遍历,但是在弄乱地图时我仍然遇到类型错误..

4

2 回答 2

2

这段代码有几个问题:

似乎您没有意识到这List[T]是一种不可变类型,这意味着一旦创建就无法更改其值。因此,如果您有 aList[T]并且您调用该::方法来添加一个值,该函数将返回一个新列表并保持您现有的列表不变。Scala 具有可变集合,例如ListBuffer其行为可能更像您期望的那样。所以当你时return l,你实际上是在返回原始列表。

另外,您使用的顺序有误::。它应该去i :: l,因为它::是一个右绑定函数(因为它以 a 结尾:)。

最后,在你的 union 方法中你正在做(other contains i). 也许只是 Scala 语法让你感到困惑,但这与做是一样的(other.contains(i)),显然contains不是parentSet. 它是类型上的一种方法List[T],但您没有调用contains列表。

您将此标记为家庭作业,因此我不会修复您的代码,但我认为您应该

  1. 查看一些涉及列表的正确 Scala 代码示例,请在此处尝试初学者

  2. 在 Scala REPL 中玩耍并尝试创建和使用一些列表,这样您就可以了解不可变集合是如何工作的。

于 2012-10-02T18:46:43.720 回答
1

要回答您的直接问题,即使 childSet 继承 parentSet 原始方法将 parentSet 指定为返回类型而不是 childSet。您可以仅使用 parentSet 作为类型,也可以将返回类型指定为继承 parentSet 的任何内容。

于 2012-10-02T21:14:53.433 回答