2016-10-29 72 views
2

TL; DR將默認參數值發送給函數?

如果我有func show(message: String = "Hello"),我怎麼可以把它的默認參數不省略參數名稱? (例如show(message: default)

注意:show()不是我要找的!詳情請參閱下文。


假設我們已經定義了以下功能:

func makeCreature(color: UIColor, eyeCount: Int = 2, noseCount: Int = 1) -> Creature { 
    // ... 
} 

那麼我們也定義了另一種方法,makeCreatures

func makeCreatures(count: Int, color: UIColor) { 
    for 1...count { 
    makeCreature(color: color) 
    } 
} 

然而,現在我們要輕鬆地​​定製eyeCount和noseCount爲makeCreatures。要做到這一點的方法之一是重新定義的參數和它們的默認值:

解決方案#1

func makeCreatures(count: Int, color: UIColor, eyeCount: Int = 2, noseCount: Int = 1) { 
    for 1...count { 
    makeCreature(color: color, eyeCount: eyeCount, noseCount: noseCount) 
    } 
} 

這樣做的問題是,如果眼睛的默認數量都沒有改變,我需要記住將其更新爲2個位置:makeCreaturemakeCreatures

什麼我希望做的反而是將方法定義:

func makeCreatures(count: Int, color: UIColor, eyeCount: Int? = nil, noseCount: Int? = nil) 

然而,這意味着現在我要創建4個不同的if分支:

解決方案#2

func makeCreatures(count: Int, color: UIColor, eyeCount: Int? = nil, noseCount: Int? = nil) { 
    for 1...count { 
    if let eyeCount = eyeCount, let noseCount = noseCount { 
     makeCreature(color: color, eyeCount: eyeCount, noseCount: noseCount) 
    } else if let eyeCount = eyeCount { 
     makeCreature(color: color, eyeCount: eyeCount) 
    } else if let noseCount = noseCount { 
     makeCreature(color: color, noseCount: noseCount) 
    } else { 
     makeCreature(color: color) 
    } 
    } 
} 

不得不創建4個不同的分支有點難以理解。有沒有更好的方法讓我的解決方案#1的簡潔性達到#2的乾燥程度?類似的東西:

理想的解決方案?

func makeCreatures(count: Int, color: UIColor, eyeCount: Int? = nil, noseCount: Int? = nil) { 
    for 1...count { 
    makeCreature(color: color, 
     eyeCount: eyeCount ?? default, 
     noseCount: noseCount ?? default) 
    } 
} 

default裝置使用默認參數值作爲makeCreature定義(即2eyeCount1noseCount)。

如果不是,那麼其他哪些解決方案可以幫助我實現這一目標?

+1

只需在兩個函數中可用的某個範圍內設置兩個Int常量,即a nd使它們成爲函數的默認參數。不需要可選項。 – BallpointBen

+1

我很好奇爲什麼你的'makeCreature'不是'Creature'上的初始化器。 – Alexander

回答

0

這不是你在尋找什麼,但你可以使用Builder模式爲這樣的:

struct Creature { 
    let color: UIColor 
    let eyeCount: Int 
    let noseCount: Int 
} 

struct CreatureBuilder { 
    var color: UIColor? 
    var eyeCount: Int = 2 //store defaults here 
    var noseCount: Int = 1 

    func build() -> Creature { 
     guard let color = color else { fatalError("Creatures need a color!") } 

     return Creature(color: color, eyeCount: eyeCount, noseCount: noseCount) 
    } 
} 

func makeCreatures(count: Int, color: UIColor, eyeCount: Int? = nil, noseCount: Int? = nil) { 
    var builder = CreatureBuilder() 
    builder.color = color; 
    if let eyeCount = eyeCount { builder.eyeCount = eyeCount } //override defaults only for non-nil params 
    if let noseCount = noseCount { builder.noseCount = noseCount } 

    for _ in 1...count { 
     let creature = builder.build() //TODO: do something with the creature. 
    } 
} 
0

爲了完整起見,有類似Alexander's另一種解決方案。

您可以創建一個struct舉行對生物的屬性:

struct Attributes { 
    let color: UIColor 
    let eyeCount: Int = 2 
    let noseCount: Int = 1 
} 

然後重新定義功能採取的屬性:

func makeCreature(attributes: Attributes) -> Creature { 
    // ... 
} 

func makeCreatures(count: Int, attributes: Attributes) { 
    for 1...count { 
    makeCreature(color: color, attributes: attributes) 
    } 
} 

,它允許您使用默認值具有這兩種功能:

// uses 2 eyes (default), and 2 noses 
makeCreature(attributes: Attributes(color: .purple, noseCount: 2)) 

// use 10 eyes, and 1 nose (default) 
makeCreatures(count: 3, attributes: Attributes(color: .blue, eyeCount: 10))