通过闭包和函数来设置属性的默认值
在使用Swift写代码的过程对于类和结构体中属性的初始化,一直是模糊不清晰的。
下面粘贴自:https://www.cnswift.org
如果某个存储属性的默认值需要自定义或设置,你可以使用闭包或全局函数来为属性提供默认值。当这个属性属于的实例初始化时,闭包或函数就会被调用,并且它的返回值就会作为属性的默认值。
这种闭包或函数通常会创建一个和属性相同的临时值,处理这个值以表示初始的状态,并且把这个临时值返回作为属性的默认值。
下面的代码框架展示了闭包是如何提供默认值给属性的:
class SomeClass {
let someProperty: SomeType = {
// create a default value for someProperty inside this closure
// someValue must be of the same type as SomeType
return someValue
}()
}
注意闭包花括号的结尾跟一个没有参数的圆括号。这是告诉 Swift 立即执行闭包。如果你忽略了这对圆括号,你就会把闭包作为值赋给了属性,并且不会返回闭包的值。
注意
如果你使用了闭包来初始化属性,请记住闭包执行的时候,实例的其他部分还没有被初始化。这就意味着你不能在闭包里读取任何其他的属性值,即使这些属性有默认值。你也不能使用隐式 self 属性,或者调用实例的方法。
下面的栗子定义了一个名为 Checkerboard 结构体,建模了一个国际象棋的棋盘。国际象棋在一个8×8的棋盘上进行,这里我们用黑白色块来代替。
为了呈现游戏的棋盘, Checkerboard 结构体只有一个名为 boardColors 的属性,它是一个包含 64 个 <color>Bool</color> 值的数组。数组中的 true 代表黑色的格子, false 代表白色的格子。数组中第一项代表棋盘的左上角方格,数组最后一项代表棋盘的右下角方格。
boardColors 数组在一个闭包里初始化,来设置它的颜色值:
struct Chessboard {
let boardColors: [Bool] = {
var temporaryBoard = [Bool]()
var isBlack = false
for i in 1...8 {
for j in 1...8 {
temporaryBoard.append(isBlack)
isBlack = !isBlack
}
isBlack = !isBlack
}
return temporaryBoard
}()
func squareIsBlackAt(row: Int, column: Int) -> Bool {
return boardColors[(row * 8) + column]
}
}
无论何时,创建一个新的 Checkboard ,闭包就会执行,并且 boardColors 的默认值就会计算和返回。上面栗子中的闭包在一个名为 temporaryBoard 的临时数组中为每个方格计算并且设置合适的颜色,然后一旦设置完毕,就把这个临时数组作为闭包的返回值返回。返回的数组值储存在 boardColors 中,并且可以通过 squareIsBlackAtRow 工具函数来查询:
let board = Chessboard()
print(board.squareIsBlackAt(row: 0, column: 1))
// Prints "true"
print(board.squareIsBlackAt(row: 7, column: 7))
// Prints "false"