'Collection'需要类型'MyCollectionClass.Element'和'Slice< MyCollectionClass>”相当于

时间:2017-06-16 00:24:57

标签: swift

我正在尝试在Swift 4中创建自定义集合类型。我已实现: startIndexendIndexindex(after:)subscript(Element)subscript(Range<Element>)并为Element分配了一个类型。为什么我会收到此错误?

extension MyCollectionClass: Collection {
    public typealias Element = MyCollectionElement

    public var startIndex: Int {
        return _values.startIndex
    }

    public var endIndex: Int {
        return _values.endIndex
    }

    public func index(after: Index) -> Index {
        return _values.index(after: after)
    }

    public subscript(position: Index) -> Element {
        return _values[position]
    }

    public subscript(bounds: Range<Index>) -> SubSequence {
        return _values[bounds]
    }
}
  

'Collection'需要类型'MyCollectionClass.Element'和'Slice&lt; MyCollectionClass&GT;”等同于

1 个答案:

答案 0 :(得分:2)

这是一个完全没用的错误消息(我鼓励你file a bug过来) - 问题有两个:

  • 您可以使用IntIndex互换地混淆编译器。
  • 您指的是SubSequence而实际上并未满足相关类型。

您可以通过定义类型别名来解决这两个问题,以便明确地满足IndexSubSequence相关类型:

public class MyCollectionClass<MyCollectionElement> {
    var _values = [MyCollectionElement]()
}

extension MyCollectionClass: Collection {

    public typealias Element = MyCollectionElement
    public typealias Index = Int

    // as ArraySlice is Array's SubSequence type.
    public typealias SubSequence = ArraySlice<MyCollectionElement>

    public var startIndex: Index {
        return _values.startIndex
    }

    public var endIndex: Index {
        return _values.endIndex
    }

    public func index(after: Index) -> Index {
        return _values.index(after: after)
    }

    public subscript(position: Index) -> Element {
        return _values[position]
    }

    public subscript(bounds: Range<Index>) -> SubSequence {
        return _values[bounds]
    }
}

虽然请注意您不必实施subscript(bounds:)要求 - Collection会为此提供默认实施,只需返回Slice<Self>

此外,如果可能,我会将您的(假设的)通用占位符重命名为Element,并让编译器推断占位符满足下标声明中的Element关联类型:

public class MyCollectionClass<Element> {
    var _values = [Element]()
}

extension MyCollectionClass: Collection {

    public typealias Index = Int

    public var startIndex: Index {
        return _values.startIndex
    }

    public var endIndex: Index {
        return _values.endIndex
    }

    public func index(after: Index) -> Index {
        return _values.index(after: after)
    }

    public subscript(position: Index) -> Element {
        return _values[position]
    }
}