【问题标题】:Polymorphism with inherited generics cause bad access in swift具有继承泛型的多态性导致快速访问不良
【发布时间】:2014-11-10 15:35:16
【问题描述】:

我有两个继承自一个泛型类的类。

class Parser<I: CollectionType, T> {
    func parse(ts: I) -> [(T, I)] { return [] }

    func parse_all(ts: I) -> [(T, I)] {
        return parse(ts).filter { isEmpty($0.1) }
    }
}

class CharParser<I: CollectionType, T> : Parser<[Character], Character> {
    let c: Character

    init(c: Character) { self.c = c }

    override func parse(ts: [Character]) -> [(Character, [Character])] {
        println(ts)
        return ts[0] == c ? [(ts[0], Array(ts[1..<ts.count]))] : []
    }
}

class AltParser<I: CollectionType, T> : Parser<I, T> {
    let p: Parser<I, T>
    let q: Parser<I, T>

    init(p: Parser<I, T>, q: Parser<I,T>) {
        self.p = p
        self.q = q
    }

    override func parse(ts: I) -> [(T, I)] {
        println(ts)
        return p.parse(ts) + q.parse(ts)
    }
}

class SeqParser<I: CollectionType, T, S>: Parser<I, (T, S)> {
    let p: Parser<I, T>, q: Parser<I,S>

    init(p: Parser<I, T>, q: Parser<I,S>) { self.p = p; self.q = q }

    override func parse(ts: I) -> [((T, S), I)] {
        var acc = [((T, S), I)]()
        for (head1, tail1) in p.parse(ts) {
            for (head2, tail2) in q.parse(tail1) {
                acc += [((head1, head2), tail2)]
            }
        }
        return acc
    }
}

打电话

let x = CharParser<[Character], Character>(c: "a")
x.parse(Array("a"))

工作正常,但是尝试通过 AltParser 调用它会导致 EXC_BAD_ACCESS

let x2 = CharParser<[Character], Character>(c: "b")
let y = AltParser(p: x, q: x2)
let z = y.parse(Array("a"))

这是编译器错误还是我误解了泛型?

【问题讨论】:

  • "调用let x = CharParser&lt;[Character], Character&gt;(c: "a"); x.parse("a") 工作正常" 真的吗?在我的机器上,它无法编译。你用的是什么版本的 Xcode?​​span>
  • @matt 抱歉,应该是x.parse(Array("a"))

标签: generics inheritance swift parser-combinators


【解决方案1】:

好的,完全没能证明你不能这样做,现在我要尝试证明你可以做到这一点。这是您的代码的一个高度简化的版本,我认为它有效(至少它可以编译并且不会崩溃):

class Parser<T> {
    func parse(ts:[T]) -> [(T, [T])] { println ("super"); return []}
}
class StringParser<T> : Parser<String> {
    let c : String
    init(c: String) { self.c=c }
    override func parse(ts:[String]) -> [(String, [String])] {
        println ("sub")
        return ts[0] == c ? [(ts[0], Array(ts[1..<ts.count]))] : []
    }
}
class AltParser<T> : Parser<T> {
    let p : Parser<T>
    init(p:Parser<T>) {
        self.p = p
    }
    override func parse(ts:[T]) -> [(T, [T])] {
        return p.parse(ts)
    }
}
func test() {
    let x = StringParser<Character>(c:"a")
    x.parse(["a"])
    let z = AltParser(p:x)
    println(z.parse(["a"]))
}

我删除了对示例来说似乎是多余的所有内容。我将 Character 变成了 String,因为我发现 Character 令人困惑。我删除了parse_all 和第二个属性q,因为您没有将它们用于任何事情。最重要的是,我从泛型中删除了整个 CollectionType,并在任何地方用显式数组替换它;那是因为 CollectionType 给我编译带来了麻烦。尤其是当我仍然在泛型中拥有 CollectionType 时,我很沮丧,因为无法找到一种方法来指定它是 T 的集合;在我看来,应该明确这一点是至关重要的。这就是我删除它并用一个显式的 T 数组替换它的原因之一。但也许我偶然发现了一些有用的东西,因为代码似乎现在可以运行了。

去把它拆开吧……!

【讨论】:

  • 谢谢你,帮助我取得了一些进展。事实证明,导致问题的不是 CollectionType,而是试图从两个泛型中专门化。不幸的是,我需要两个泛型,所以看起来我被困住了,直到苹果修复了这个错误。我已经更新了我的帖子,以说明为什么我需要至少两个泛型,任何帮助以使其正常工作将不胜感激。
猜你喜欢
  • 2014-06-01
  • 2019-03-08
  • 2018-01-19
  • 2020-05-17
  • 1970-01-01
  • 2015-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多