如何在不崩溃编译器的情况下实现MutableCollectionType?

时间:2015-12-02 13:16:57

标签: swift

我习惯了一个永远崩溃的Swift编译器,通常有很多可用的解决方法。 但是这次我无法成功地使结构符合MutableCollectionType

只要您不取消MutableCollectionType一致性,就可以将附加的示例粘贴到Playground中。 我避免了所有方法的具体实现,以缩小崩溃的原因(因此所有fatalError())。但即使正确实现这些方法,编译器也会崩溃。

有没有人知道如何解决这个编译器崩溃的问题?

struct Test {}


struct TestCollection: CollectionType {

    typealias Index = Int


    private var values: [Test]


    var count: Int {
        fatalError()
    }


    var endIndex: Int {
        fatalError()
    }


    func generate() -> IndexingGenerator<Array<Test>> {
        fatalError()
    }


    var isEmpty: Bool {
        fatalError()
    }


    subscript(bounds: Range<Int>) -> ArraySlice<Test> {
        fatalError()
    }


    subscript(position: Int) -> Test {
        get { fatalError() }
        mutating set { fatalError() }
    }


    var startIndex: Int {
        fatalError()
    }
}


// uncommenting the following line crashes the compiler
// extension TestCollection: MutableCollectionType {}

1 个答案:

答案 0 :(得分:2)

是的,解决编译器崩溃非常困难。但是,有一些技巧很有用。首先,如果您编译它并且它是segfaults(因为这对我来说当前正在做),您仍然可以在Xcode中进入错误,它可能会为您提供更多信息。

或者,您可以尝试将崩溃减少到最小的工作示例,以查看哪个部分崩溃了编译器。实际上,MutableCollectionType一致性的最小方法集实际上非常小:

struct Test {}

struct TestCollection: MutableCollectionType {

  var startIndex: Int { fatalError() }

  var endIndex: Int { fatalError() }

  subscript(position: Int) -> Test {
    get { fatalError() }
    mutating set { fatalError() }
  }

}

所以现在我们可以逐个添加你的额外内容,直到它崩溃。碰巧的是,typealiascountgenerate()isEmpty实际上更好地被排除在外。推断typealiascountisEmpty可以根据startIndexendIndex进行计算(并且就像您编写的一样有效率自己的方法),generate()方法可以在集合本身而不是数组上返回IndexingGenerator

所以重新添加的唯一内容是ranged下标:

extension TestCollection {
  subscript(range: Range<Int>) -> ArraySlice<Test> {
    fatalError()
  }
}

仔细观察一下,你可能会用不同的方式写出来:

extension TestCollection {
  subscript(range: Range<Int>) -> ArraySlice<Test> {
    get { fatalError() }
    set { fatalError() }
  }
}

没有错误!

只是一个小小的注释:看起来就像你在Array结构Test周围实现了一个非常轻量级的包装器。由于正确遵循所有必需协议所涉及的复杂性,可能最好只是扩展Array以提供您需要的功能,或者像这样扩展MutableCollectionType

extension MutableCollectionType where Generator.Element == Test {...