快速错误:&#39;序列&#39;需要类型&#39; T&#39;和&#39; ArraySlice <t>&#39;相当于

时间:2017-08-14 06:20:20

标签: swift swift4

我尝试更新数学库以与Swift 3兼容,但我遇到了错误:

'Sequence' requires the types 'T' and 'ArraySlice<T>' be equivalent

关于Sequence的Apple文档建议makeIterator()方法返回一个迭代器。并且似乎迭代器返回grid变量中的一个元素,该变量是变量T。我不太清楚我在这里失踪了什么。任何意见将是有益的。

public struct Matrix<T> where T: FloatingPoint, T: ExpressibleByFloatLiteral {
    public typealias Element = T

    let rows: Int
    let columns: Int
    var grid: [Element]

    public init(rows: Int, columns: Int, repeatedValue: Element) {
        self.rows = rows
        self.columns = columns

        self.grid = [Element](repeating: repeatedValue, count: rows * columns)
    }
... 
}

extension Matrix: Sequence { // <-- getting error here
    public func makeIterator() -> AnyIterator<ArraySlice<Element>> {
        let endIndex = rows * columns
        var nextRowStartIndex = 0

        return AnyIterator {
            if nextRowStartIndex == endIndex {
                return nil
            }

            let currentRowStartIndex = nextRowStartIndex
            nextRowStartIndex += self.columns

            return self.grid[currentRowStartIndex..<nextRowStartIndex]
        }
    }
}

1 个答案:

答案 0 :(得分:4)

Your code compiles fine as Swift 3.1 (Xcode 8.3.3). The error

'Sequence' requires the types 'T' and 'ArraySlice<T>' be equivalent

occurs when compiling as Swift 4 (Xcode 9, currently beta), because then the Sequence protocol already defines the

associatedtype Element where Self.Element == Self.Iterator.Element

which conflicts with your definition. You can either choose a different name for your type alias, or just remove it (and use T instead):

public struct Matrix<T> where T: FloatingPoint, T: ExpressibleByFloatLiteral {

    let rows: Int
    let columns: Int
    var grid: [T]

    public init(rows: Int, columns: Int, repeatedValue: T) {
        self.rows = rows
        self.columns = columns

        self.grid = [T](repeating: repeatedValue, count: rows * columns)
    }
}

extension Matrix: Sequence {
    public func makeIterator() -> AnyIterator<ArraySlice<T>> {
        let endIndex = rows * columns
        var nextRowStartIndex = 0

        return AnyIterator {
            if nextRowStartIndex == endIndex {
                return nil
            }

            let currentRowStartIndex = nextRowStartIndex
            nextRowStartIndex += self.columns

            return self.grid[currentRowStartIndex..<nextRowStartIndex]
        }
    }
}

This compiles and runs with both Swift 3 and 4.