【发布时间】:2023-03-18 08:13:01
【问题描述】:
所以我一直在玩protocol witness types,它们本质上是协议的具体实现。假设我们有一个协议可以打折一件商品,返回双倍。
而不是这个:
protocol Discountable {
func discount() -> Double
}
一个人这样做:
struct Discounting<A> {
let discount: (A) -> Double
}
而且,不是像这样使一个类型符合Discountable 协议:
extension Double: Discountable {
func discount() -> Double {
return self * 0.9
}
}
一个类型可以提供多种具体实现:
extension Discounting where A == Double {
static let tenPercentOff = Self { amount in
amount * 0.9
}
static let fiveDollarsOff = Self { amount in
amount - 5
}
}
但是,我想知道如何合并多个这些折扣。这是我最初的草图:
static func combine(_ discounts: [Discounting<A>]) -> Discounting<A> {
Discounting { (amount: A) -> Double in
return discounts.reduce(0.0) { current, discount in
// ??
}
}
}
但是,我不确定要在 reduce 闭包中放什么。
如何将这些Discounting 类型中的多个合并为一个?
【问题讨论】:
-
我刚刚阅读了链接的文章。看来您可能对这种模式有一点误解。
-
我不太清楚你为什么这么认为——本文的一位作者围绕这种模式创建了一个验证库,它还实现了“组合”功能:swift-validations。但是,我不想结合验证,而是想结合折扣——例如结合示例中的 10% 折扣和 5 美元折扣。
-
好吧,也许你没有误解pattern,但你肯定误解了
Discounting代表的类型。无论如何,组合验证器与您在这里得到的有点不同,即验证器不相互依赖——它们的顺序无关紧要。 OTOH,折扣的顺序很重要 - 每个折扣的结果取决于前一个的结果。 -
我重读了这篇文章,对用例有了更多的了解。您似乎也想对对象的不同部分应用折扣(例如
shippingAmount和amount)?那么我认为使用(A) -> A作为函数类型将是最好的替代设计。请参阅我编辑的答案。Discounting的设计目前不支持组合折扣。 “其他人也用这种模式实现了一个组合函数”在这里并不是一个很好的论点。这种模式与您是否可以实现combine函数并没有真正的关系。
标签: swift swift-protocols