protocol PriceCalculatable {}
extension Int : PriceCalculatable {}
extension Double : PriceCalculatable {}
class PriceCalculator {
static func culculateFinalPrice<T: PriceCalculatable>(for products: [Product],
applying coupon: Coupon?) -> T {
let x = products.reduce(0) { price, product in
return price + product.price
}
var finalPrice = Double(x)
if let coupon = coupon {
let multiplier = coupon.discountPercentage / 100
let discount = Double(finalPrice) * Double(multiplier)
finalPrice -= Double(discount)
}
return finalPrice
}
}
我收到一条错误消息:
无法将类型为“ Double”的返回表达式转换为类型为“ T”
尽管该错误是有道理的,但我不理解为什么Double
和Int
符合该类型却无法返回
答案 0 :(得分:3)
假设您的方法可以编译,
让我们创建另一种符合PriceCalculatable
的类型:
struct Foo : PriceCalculatable {}
现在,我们尝试调用您的方法:
let foo: Foo = PriceCalculator.culculateFinalPrice(for: someProducts, applying: myCoupon)
从编译器的角度来看,以上编译,但是这导致运行时不一致。运行时如何将Double
(finalPrice
)转换为Foo
?
因此,您的方法不应编译。
要使其生效,您可以创建一个ConvertileFromDouble
协议并使Int
和Double
符合该协议。在该协议中,您需要指定一个以Double
作为参数的初始化程序。
protocol ConvertibleFromDouble {
init(_ doubleValue: Double)
}
extension Int: ConvertibleFromDouble {
}
extension Double: ConvertibleFromDouble {
}
class PriceCalculator {
static func culculateFinalPrice<T: ConvertibleFromDouble>(for products: [Product],
applying coupon: Coupon?) -> T {
...