2016-06-19 48 views
2

一个类有一些变量需要在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

你可以在报关行分配值,而忽略'init' – vadian

回答

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

更新:Code's answer belowImplicitly 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实例,但要绕过编译器,必须使您的属性成为可选项。该解决方案有一个明确的伊克因素:

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 
    } 
} 

这使我们回到问题的心脏:迅速要求所有属性是可选的或初始化。另一种解决方案是简单地给出所有的属性值(无意义或无意义)。缺点是属性定义可能会误导有人第一次阅读代码。

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

+1

我们必须已在同一时间编辑,伟大的人笑 – Haligen

1

使用隐式展开自选。

class Foo { 
    var varA: Int! 
    var varB: Int! 
    var varC: Int! 

    init() { 
     restoreInitValues() 
    } 

    func restoreInitValues() { 
     varA = 10 
     varB = 20 
     varC = 30 
    } 
}