我正在定义一个具有“下标”功能的协议(用于信息隐藏目的),同时具有getter和setter。 然后我定义了一个实现该协议的类。
问题的简短版本:如果我在类的对象上使用下标(作为左值,从而使用setter),一切都按预期工作。如果我在刚刚声明为协议类型的对象上执行此操作,则会出现“无法分配此表达式的结果”错误。
长版。 我有一个Int的董事会。板是2D矩阵。我通过BoardType协议公开了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
相反,如果我使用原型,我会收到错误
let board : BoardType = Board(width: 4, height: 4)
board[1,1] = 10
为什么?
答案 0 :(得分:17)
编译器正在执行此操作,因为您已使用let
声明了第二个并且可能是值类型,在这种情况下,下标setter将是一个变异表达式。两个修复 - 在使用var
声明时使用BoardType
:
var board : BoardType = Board(width: 4, height: 4)
board[1,1] = 10
或使BoardType
成为一个类协议:
protocol BoardType: class {
var width: Int {get}
var height: Int {get}
subscript(x:Int, y:Int) -> Int {get set}
}