我习惯了一个永远崩溃的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 {}
答案 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() }
}
}
所以现在我们可以逐个添加你的额外内容,直到它崩溃。碰巧的是,typealias
,count
,generate()
和isEmpty
实际上更好地被排除在外。推断typealias
,count
和isEmpty
可以根据startIndex
和endIndex
进行计算(并且就像您编写的一样有效率自己的方法),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 {...