2015-05-06 45 views
2

我想爲某些初始化參數提供默認值。我希望能夠在子類中重複使用相同的默認值,但沒有找到一種方法來做到這一點。如何避免子類中的默認初始參數冗餘?

第一次嘗試 - 參數的默認值:

class A { 

    typealias Mapper = (A) -> String 

    let mapper: Mapper 

    init(mapper: Mapper = {a in "foo"}) { 
     self.mapper = mapper 
    } 

} 

class B: A { 

    let myVar: Int 

    init(myVar: Int, mapper: Mapper = {a in "foo"}) { 
     self.myVar = myVar 

    } 
} 

let b: B = B(myVar: 1) 
let str = b.mapper(b) 
let b2: B = B(myVar: 2, mapper: {a in "bar"}) 

我有兩次指定默認值(A和B中INIT),以便能夠有或沒有默認值來初始化B中。

我也試圖與便利的初始化,同樣的問題:

class A { 

    typealias Mapper = (A) -> String 

    let mapper: Mapper 

    convenience init() { 
     self.init(mapper: {a in "foo"}) 
    } 

    init(mapper: Mapper) { 
     self.mapper = mapper 
    } 

} 

class B: A { 

    let myVar: Int 

    convenience init(myVar: Int) { 
     self.init(myVar: myVar, mapper: {a in "foo"}) 
    } 

    init(myVar: Int, mapper: Mapper) { 
     self.myVar = myVar 

     super.init(mapper: mapper) 
    } 
} 

我想,也許至少我把默認值在一個靜態變量,就像這樣:

class A { 

    typealias Mapper = (A) -> String 

    static let defMapper: Mapper = {a in "foo"} 

    let mapper: Mapper 

    convenience init() { 
     self.init(mapper: A.defMapper) 
    } 

    init(mapper: Mapper) { 
     self.mapper = mapper 
    } 

} 

class B: A { 

    let myVar: Int 

    convenience init(myVar: Int) { 
     self.init(myVar: myVar, mapper: A.defMapper) 
    } 

    init(myVar: Int, mapper: Mapper) { 
     self.myVar = myVar 

     super.init(mapper: mapper) 
    } 
} 

(也有可能定義變量爲懶惰,以避免在不使用默認參數時進行初始化)。

這個工作,直到我添加到A通用類型然後我得到「靜態屬性尚未支持泛型類型」。所以我必須在類之外放置默認值,這也導致必須將typealias定義放在類之外,如果我將泛型添加到混合中,這會非常混亂。

有沒有辦法解決這個問題?

回答

2

如何使用計算性能:

class A<T> { 

typealias Mapper = (A) -> String 

static var defMapper: Mapper { 
    return { a in "foo" } 
} 

let mapper: Mapper 

convenience init() { 
    self.init(mapper: A.defMapper) 
} 

init(mapper: Mapper) { 
    self.mapper = mapper 
} 

} 

class B<T>: A<T> { 

    let myVar: Int 

    convenience init(myVar: Int) { 
     self.init(myVar: myVar, mapper: A.defMapper) 
    } 

    init(myVar: Int, mapper: Mapper) { 
     self.myVar = myVar 

     super.init(mapper: mapper) 
    } 
} 

let b: B = B<String>(myVar: 1) 

let str = b.mapper(b) 

let b2: B = B<String>(myVar: 2, mapper: {a in "bar"}) 

A<Int>(mapper: {a in "bar"}) 

A<Int>() 

或類型的方法:

class A<T> { 

    typealias Mapper = (A) -> String 

    static func defMapper() -> Mapper { 
     return { a in "foo" } 
    } 

    let mapper: Mapper 

    convenience init() { 
     self.init(mapper: A.defMapper()) 
    } 

    init(mapper: Mapper) { 
     self.mapper = mapper 
    } 

} 

class B<T>: A<T> { 

    let myVar: Int 

    convenience init(myVar: Int) { 
     self.init(myVar: myVar, mapper: A.defMapper()) 
    } 

    init(myVar: Int, mapper: Mapper) { 
     self.myVar = myVar 

     super.init(mapper: mapper) 
    } 
} 

let b: B = B<String>(myVar: 1) 

let str = b.mapper(b) 

let b2: B = B<String>(myVar: 2, mapper: {a in "bar"}) 

A<Int>(mapper: {a in "bar"}) 

A<Int>() 
+0

啊,沒有想到這一點。我以爲我錯過了與初始化程序相關的東西,所以我沒有足夠的探索「替代方法」。謝謝! – Ixx