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)
}
}
但是,现在我们想要轻松自定义makeCreatures
的eyeCount和noseCount。一种方法是重新定义参数及其默认值:
解决方案#1
func makeCreatures(count: Int, color: UIColor, eyeCount: Int = 2, noseCount: Int = 1) {
for 1...count {
makeCreature(color: color, eyeCount: eyeCount, noseCount: noseCount)
}
}
问题在于,如果眼睛的默认数量发生变化,我需要记住在两个地方更新它:makeCreature
和makeCreatures
。
我希望做的是将方法定义为:
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个不同的分支有点难看并且难以理解。是否有更好的方法可以让我在#2的干燥度下获得解决方案#1的简洁性?类似的东西:
理想解决方案?
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
中定义的默认参数值(2
eyeCount
和1
noseCount
)。
如果没有,那么可以帮助我实现这一目标的其他解决方案是什么?
答案 0 :(得分:0)
这并不是您正在寻找的,但您可以使用构建器模式:
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.
}
}
答案 1 :(得分:0)
为了完整起见,还有另一种类似于Alexander's的解决方案。
您可以创建一个结构来保持生物的属性:
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))