Swift 初始化“self”类型`
这很有效Swift 初始化“self”类型`,swift,Swift,这很有效 class Die { let faces: Int required init(faces: Int) { self.faces = faces } func yahtzeeDice() -> [Die] { return [Die](repeating: type(of: self).init(faces: 6), count: 5) } } 这似乎违反了干法。可以在yahtzeeDice函数中间接
class Die {
let faces: Int
required init(faces: Int) {
self.faces = faces
}
func yahtzeeDice() -> [Die] {
return [Die](repeating: type(of: self).init(faces: 6), count: 5)
}
}
这似乎违反了干法。可以在
yahtzeeDice
函数中间接引用Die
。首先,请注意,问题中[Die]
数组的重复初始值设定项将实例化单个Die
实例,然后在数组中重复引用该实例5次(因为Die
是引用类型)。也就是说,在您的示例中,[Die]
的所有成员都对相同的基础Die
实例进行了强引用。因此,如果使用引用类型,请记住避免重复数组初始值设定项
现在,您可以构建一个协议,该协议提供blueprinted
static
dice supplier方法的默认实现,该方法使用其他blueprinted初始值设定项提供一个Self
实例数组
// the 'class' requirement not strictly needed here, but it holds semantic
// value to explain the 'map' call rather than using array:s 'repeating'
// initializer in in the default implementation below
protocol DiceFactory: class {
init(faces: Int, id: Int)
static func dice(_ n: Int) -> [Self]
}
extension DiceFactory {
static func dice(_ n: Int) -> [Self] {
return (1...n).map { Self.init(faces: 6, id: $0) }
}
}
如果您标记您的Dice
类final
(为什么final
?请参阅下面链接的Q&A),则在遵守DiceFactory
协议时,您可以直接访问此默认实现
final class Die: DiceFactory {
let id: Int
let faces: Int
init(faces: Int, id: Int) {
self.faces = faces
self.id = id
}
}
let myDice = Die.dice(5)
myDice.forEach { print($0, $0.id) }
/* Die 1
Die 2
Die 3
Die 4
Die 5 */
但问题是,您是否有充分的理由不显式键入Die
另见:
yahtzeeDice()
的方法签名中的[Die]
还是主体?后者可以被数组
替换,因为可以推断Die
的元素类型。无关:为什么yahtzeeDice()
实例方法?您可以将其设置为静态/类方法,只需使用self
而不是类型(of:self)
。您不能在签名中使用[self]
,因为数组是一个结构,如果a:B
则[a]
和[B]
仍然是不相关的类型。还要注意上面的[Die]
数组的重复初始值设定项实例化了一个Die
实例,然后在数组中重复引用该实例5次(因为Die
是引用类型)。即[Die]的所有成员
持有对同一基础实例的强引用。间接引用它的目的是什么,即,您试图解决什么问题?您是否计划经常更改类的名称?一个小的改进,您可以使用(1…n).map{Self.init(…)}
生成数组。请注意,使用数组(重复:count:)
可能是有意的,因为Die
实例是不可变的(OP可能只是使用一个类进行继承——如果不是这样,那么它肯定应该是一个struct
)。