我很难找到有关如何符合 MutableCollection 的文档。谷歌在这个话题上完全空白。

示例 ,我想为 GMSPath / GMSMutablePath 添加一致性:

import CoreLocation
import GoogleMaps

extension GMSPath: RandomAccessCollection {

    public var startIndex: Int {
        return 0
    }

    public var endIndex: Int {
        return count
    }

    public func index(before i: Int) -> Int {
        return i-1
    }

    public func index(after i: Int) -> Int {
        return i+1
    }

    public subscript(position: Int) -> CLLocationCoordinate2D {
        return coordinate(at: UInt(position))
    }
}

extension GMSMutablePath: MutableCollection {  // Error!

    public override subscript(position: Int) -> CLLocationCoordinate2D {
        get {
            return coordinate(at: UInt(position))
        }
        set {
            replaceCoordinate(at: UInt(position), with: newValue)
        }
    }
}



MutableCollection 的文档说明:



我就是这么做的。
MutableCollection 继承自 MutableIndexable ,文档说明:



嗯?

最佳答案

这里的问题是我也符合 RandomAccessCollection 而不仅仅是 Collection/MutableCollection 。在这种情况下,与文档 promise 的相反,我们要做的不仅仅是提供一个下标 setter 。具体来说,需要实现切片下标。

我最终得到了以下结果。 typaliases 是必要的,因为编译器似乎不能总是推断它们。

 extension GMSPath: RandomAccessCollection {

    public typealias Index = Int
    public typealias Indices = DefaultRandomAccessIndices<GMSPath>

    public var startIndex: Index {
        return 0
    }

    public var endIndex: Index {
        return count
    }

    public func index(before i: Index) -> Index {
        return i-1
    }

    public func index(after i: Index) -> Index {
        return i+1
    }

    public subscript(position: Index) -> CLLocationCoordinate2D {
        return coordinate(at: UInt(position))
    }
}

extension GMSMutablePath: MutableCollection {

    public subscript(bounds: Range<Index>) -> RandomAccessSlice<GMSPath> {
        get { return .init(base: self, bounds: bounds) }
        set {
            assert(newValue.count == bounds.count)
            newValue.enumerated().forEach { self[$0] = $1 }
        }
    }

    public override subscript(position: Index) -> CLLocationCoordinate2D {
        get { return coordinate(at: UInt(position)) }
        set { replaceCoordinate(at: UInt(position), with: newValue) }
    }
}

使用 Swift 的条件默认协议(protocol)实现,我发现很难找出到底需要实现什么。

10-07 18:22