swift - swift 中的下标和协议(protocol)

标签 swift protocols subscript

我正在定义一个协议(protocol),出于抽象目的,它有一个带有 getter 和 setter 的“下标”函数。 然后我定义了一个实现该协议(protocol)的类。

问题的简短版本:如果我在类的对象上使用下标(作为左值,因此使用 setter),一切都按预期工作。如果我对刚刚声明的协议(protocol)类型的对象执行此操作,我会收到“无法分配给该表达式的结果”错误。

长版。 我有一个国际委员会。板是一个二维矩阵。我通过 BoardType 协议(protocol)公开 Board 类型。

protocol BoardType {
    var width: Int { get }
    var height: Int { get }
    subscript(x: Int, y: Int) -> Int { get set }
}

class Board: BoardType {

    let width, height: Int
    var matrix: Array2D<Int>

    init(width: Int, height: Int) {
        self.width = width
        self.height = height
        matrix = Array2D<Int>(cols: width, rows: height, defaultValue: 0)
    }

    subscript(x: Int, y: Int) -> Int {
        get {
            return matrix[x, y]
        }
        set {
            matrix[x, y] = newValue
        }
    }
}

Array2D 的实现是标准的:

class Array2D<T> {

    var cols: Int, rows: Int
    var matrix: [T]

    init(cols: Int, rows:Int, defaultValue: T) {
        self.cols = cols
        self.rows = rows
        matrix = Array(count: cols*rows, repeatedValue: defaultValue)
    }

    subscript(x: Int, y: Int) -> T {
        get {
            return matrix[cols * y + x]
        }
        set {
            matrix[cols * y + x] = newValue
        }
    }

    func colCount() -> Int {
        return self.cols
    }

    func rowCount() -> Int {
        return self.rows
    }
}

现在,如果我执行以下操作,它会起作用:

    let board = Board(width: 4, height: 4)
    board[1, 1] = 10

相反,如果我使用原型(prototype),我会得到错误

    let board : BoardType = Board(width: 4, height: 4)
    board[1, 1] = 10

为什么?

最佳答案

编译器这样做是因为你已经用 let 声明了第二个,它可能是一个值类型,在这种情况下,下标 setter 将是一个可变的表达。两个修复 - 在使用 BoardType 声明时使用 var:

var board : BoardType = Board(width: 4, height: 4)
board[1,1] = 10

或者使BoardType成为类协议(protocol):

protocol BoardType: class {
    var width: Int {get}
    var height: Int {get}
    subscript(x:Int, y:Int) -> Int {get set}
}

关于swift - swift 中的下标和协议(protocol),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26812464/

相关文章:

ios - SwiftUI 误导性错误 : 'Int' is not convertible to 'CGFloat'

testing - OpenID 提供商的合规性测试

c++ - Protocol Buffers - 为什么 int32 和 sint32 以相同的方式映射?

swift - 如何将生成协议(protocol)声明为委托(delegate)?

Swift 3 下标范围适用于第一个集群但不适用于中间

ios - 含糊不清地使用 'subscript' 与 NSArray & JSON

ios - 如何使用核心数据类中的所有对象创建一个字符串

ios - Swift 如何从 CollectionviewCell 中提取 indexPath 值?

ios - updatesearchresultsforsearchcontroller 未调用

arrays - 仅在真实设备上使用下标错误的歧义