Swift Class 中的初始化器
Initializer in a Swift Class
我从其他语言来到Swift。我有时会使用一种模式来定义 class,其中初始化器调用另一个函数,稍后将调用该函数来重新初始化。
class Test {
var thing: String
init() {
reinit() // 'self' used in method call 'load' before all stored properties are initialized
} // Return from initializer without initializing all stored properties
func renit() {
self.thing = "Hello"
}
}
在这种情况下,它不起作用。实在不想把初始化代码写两遍,又不能用test.init()
,显然要重新初始化
正确的做法是什么?
更新
一些评论表明这是一个糟糕的设计,而且很可能是这样。当然在现实中,应用不会那么琐碎。
关键是我可以用其他语言这样做,所以我想知道Swift中正确的方法是什么。
一种方法是使 thing
成为隐式展开的可选。这听起来很危险,但它实际上只是对几乎所有其他语言所做的回归(例如 Java、Ruby、Python、JS,其中所有对象引用的行为都像 IUO)。
或者,您复制作业。如果值很复杂,你可以像这样提取:
class Test {
var thing: String
init() {
self.thing = generateThing()
}
func renit() {
self.thing = generateThing()
}
func generateThing() -> String { "Hello" }
}
如果您的对象可以是“re-initialized”,那么默认情况下只需将其初始化为一些 base-state:
class Test {
var thing: String = "" // Add default value
init() {
reinit()
}
func reinit() {
self.thing = "Hello"
}
}
通常,我认为这可能是一个糟糕的设计。不是“重新初始化”,而是用一个结构替换这个 class ,然后把它扔掉并在你想重置的时候替换它。通常,结构的创建成本非常低。但是如果你需要这个,那么默认值就可以了。
我从其他语言来到Swift。我有时会使用一种模式来定义 class,其中初始化器调用另一个函数,稍后将调用该函数来重新初始化。
class Test {
var thing: String
init() {
reinit() // 'self' used in method call 'load' before all stored properties are initialized
} // Return from initializer without initializing all stored properties
func renit() {
self.thing = "Hello"
}
}
在这种情况下,它不起作用。实在不想把初始化代码写两遍,又不能用test.init()
,显然要重新初始化
正确的做法是什么?
更新
一些评论表明这是一个糟糕的设计,而且很可能是这样。当然在现实中,应用不会那么琐碎。
关键是我可以用其他语言这样做,所以我想知道Swift中正确的方法是什么。
一种方法是使 thing
成为隐式展开的可选。这听起来很危险,但它实际上只是对几乎所有其他语言所做的回归(例如 Java、Ruby、Python、JS,其中所有对象引用的行为都像 IUO)。
或者,您复制作业。如果值很复杂,你可以像这样提取:
class Test {
var thing: String
init() {
self.thing = generateThing()
}
func renit() {
self.thing = generateThing()
}
func generateThing() -> String { "Hello" }
}
如果您的对象可以是“re-initialized”,那么默认情况下只需将其初始化为一些 base-state:
class Test {
var thing: String = "" // Add default value
init() {
reinit()
}
func reinit() {
self.thing = "Hello"
}
}
通常,我认为这可能是一个糟糕的设计。不是“重新初始化”,而是用一个结构替换这个 class ,然后把它扔掉并在你想重置的时候替换它。通常,结构的创建成本非常低。但是如果你需要这个,那么默认值就可以了。