一个类有一些变量要在init()
中初始化,同时,该类提供了一个函数,可以将这些变量恢复为restoreInitValues()
中的初始值。有没有办法在没有在init()
和restoreInitValues()
内设置两次这些值(重复代码)的情况下实现这一目标?
class Foo {
var varA: Int
var varB: Int
var varC: Int
init() {
//restoreInitValues() // error: call method before all stored proproties are initalized
//or I have to have duplicate code here as restoreInitValues below
varA = 10
varB = 20
varC = 30
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
答案 0 :(得分:1)
我个人会将3个默认值分配给3个类范围常量,然后使用这些值进行初始化和恢复。如果需要,还可以在init中消除赋值语句,并在声明var时分配值。此外,如果您需要在类中添加任何其他函数,则可以将类中的默认值定义为常量。
class Foo {
let defaultA = 10
let defaultB = 20
let defaultC = 20
var varA: Int
var varB: Int
var varC: Int
init() {
varA = defaultA
varB = defaultB
varC = defaultC
}
func restoreInitValues() {
varA = defaultA
varB = defaultB
varC = defaultC
}
}
您还可以定义一个结构,使用它来赋值,然后使用重置函数进行初始化。
struct values{
static let defaultA = 10
static let defaultB = 20
static let defaultC = 30
}
class test {
var a: Int = 0
var b: Int = 0
var c: Int = 0
init(){
resetValues()
}
func resetValues(){
(a, b, c) = (values.defaultA, values.defaultB, values.defaultC)
}
}
答案 1 :(得分:1)
更新:Code's answer below关于Implicitly Unwrapped Optionals就是答案。我不确定为什么我以前在文档中找不到它。我要留下我的答案给后人,但你应该接受Code's answer。
刚接触swift,我试了一下,找到了这两个解决方案,但我不确定它们是不是最好的解决方案。
问题似乎是swift努力确保在执行初始化之后没有类实例将具有未初始化的属性(除非它们被标记为可选)。它不会让您调用非静态方法,因为您可能在设置所有属性之前使用该实例。此外,它不相信你会调用另一个为你初始化所有属性的方法,大概是因为这很难验证。
对于类,使用私有静态方法返回默认值:
class Foo {
//...
init() {
(varA, varB, varC) = Foo.defaultValues()
}
func restoreInitValues() {
(varA, varB, varC) = Foo.defaultValues()
}
static private func defaultValues() -> ( Int, Int, Int ) {
return (10, 20, 30)
}
}
如果您不需要类,则可以按值复制结构:
struct Foo {
//...
mutating func restoreInitValues() {
self = Foo()
}
}
或者您可以放弃restoreInitValues()
并执行此操作:
var f = Foo()
f.varA = 10000
// instead of resetting the internal state of `f`, just replace it with
// a new `Foo` instance
f = Foo()
或者您可以使用修改Foo实例的静态私有方法,但要绕过编译器,您必须使属性成为可选。这个解决方案有一个明确的Ick因素:
class Foo {
var varA: Int?
var varB: Int?
var varC: Int?
init() {
Foo.resetValues(in: self)
}
func restoreInitValues() {
Foo.resetValues(in: self)
}
static private func resetValues(in foo: Foo) {
foo.varA = 10
foo.varB = 20
foo.varC = 30
}
}
这使我们回到问题的核心:swift要求所有属性都是可选的或初始化的。另一种解决方案是简单地给出所有属性值(无意义或无意义)。缺点是属性定义可能会误导第一次阅读代码的人。
class Foo {
var varA = -1
var varB = -1
var varC = -1
init() {
restoreInitValues()
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}
最后,请查看此类似问题的答案:How to implement two inits with same content without code duplication
答案 2 :(得分:1)
使用隐式解包的选项。
class Foo {
var varA: Int!
var varB: Int!
var varC: Int!
init() {
restoreInitValues()
}
func restoreInitValues() {
varA = 10
varB = 20
varC = 30
}
}