【发布时间】:2018-03-13 00:06:16
【问题描述】:
这是一个例子。编写一个将两个双精度相乘的函数非常简单:
func MultiplyDoubles(_ x: Double, _ y: Double) {
return x * y
}
MultiplyDoubles(3,5) // returns 15
但假设我想编写一个通用函数来执行此操作:
func MultiplyValues<T>(_ x: T, _ y: T) {
return x * y //ERROR
}
MultiplyValues(3, 5)
但这会引发错误:Binary operator '*' cannot be applied to to 'T' operands。
我知道我需要编写一个协议来指定* 可以应用于它,但我该怎么做呢?
我试过了:
protocol Multipliable {
static func *(A:Multipliable, B: Multipliable) -> Multipliable
}
func MultiplyValues<T: Multipliable>(_ x: T, _ y: T) -> Multipliable {
return x * y
}
MultiplyValues(3, 5)
虽然这会返回消息
error: MyPlayground.playground:15:19: error: argument type 'Int' does not conform to expected type 'Multipliable'
MultiplyValues(3, 5)
^
研究: 我已经查看了protocols 的文档以及generics 和operators 的文档。我不是在写一个通用协议,而是一个普通协议,旨在指定它可以成倍增加。该文档解释了如何重载运算符,以及如何创建泛型函数,以及如何使用具有泛型函数的协议,但没有一个解释如何编写一个协议来指定一个运算符可以应用于协议。
【问题讨论】:
-
编辑您的问题并讨论您在 google 搜索通用协议时发现了什么,以及为什么它对您没有帮助。
-
Rob 的回答恰到好处 IMO,但在你走得太远之前,请务必阅读 oleb.net/blog/2016/12/protocols-have-semantics。 “
*可以应用于它”与“可以相乘”不是一回事。如果您想要的是“可以成倍增加”,那么您需要一个协议来定义其语义(就像 Numeric 所做的那样),而不仅仅是语法。