我正在尝试创建2个协议ArithmeticType和MathematicType,它们将用于泛型运算符函数的where子句 protocol ArithmeticType { func +(lhs: Self, rhs: Self) - Self func -(lhs: Self, rhs: Self) - Self func *(lhs: Self, rhs: Self)
protocol ArithmeticType {
func +(lhs: Self, rhs: Self) -> Self
func -(lhs: Self, rhs: Self) -> Self
func *(lhs: Self, rhs: Self) -> Self
func /(lhs: Self, rhs: Self) -> Self
}
extension Int : ArithmeticType {
}
extension Double : ArithmeticType {
}
extension Float : ArithmeticType {
}
ArithmeticType按预期工作,Int,Float和Double符合它.但是以下失败了
import Darwin
protocol MathematicType {
func sin(x: Self) -> Self
}
extension Double : MathematicType {
}
extension Float : MathematicType {
}
我在游乐场的控制台输出上读到:
Playground execution failed: <EXPR>:35:1: error: type 'Double' does not conform to protocol 'MathematicType'
extension Double : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Double -> Self'
func sin(x: Self) -> Self
^
<EXPR>:39:1: error: type 'Float' does not conform to protocol 'MathematicType'
extension Float : MathematicType {
^
<EXPR>:32:10: note: protocol requires function 'sin' with type 'Float -> Self'
func sin(x: Self) -> Self
^
我希望数学函数的行为与上面的运算符相似.有什么办法吗?
==编辑:
现在我意识到试图简化我的问题是一个坏主意.上下文是这个类(可选值的向量)
class Vector<T> {
var data=[T?]()
init(fromArray: Array<T>) {
for i in fromArray {
data.append(i)
}
}
init() {
}
init(count: Int){
for i in 0..<count {
data.append(nil)
}
}
init(count: Int, repeatedValue: T) {
for i in 0..<count {
data.append(repeatedValue)
}
}
func count() -> Int {
return data.count
}
func append(newElement: T?) {
data.append(newElement)
}
subscript(index: Int) -> T? {
let i = index>0 ? index % count() : -index % count()
return data[i]
}
}
在它之外我为操作符定义了一个通用函数
func +<T where T: ArithmeticType>(left: Vector<T>, right: Vector<T>) -> Vector<T> {
let resultCount = max(left.count(),right.count())
var result = Vector<T>()
for i in 0..<resultCount {
if left[i] != nil && right[i] != nil {
result.append(left[i]!+right[i]!)
}
else {
result.append(nil)
}
}
return result
}
这是按预期工作的,但是当我试图将一般的sin函数定义为
func sin<T where T : FloatingPointType>(x: Vector<T>) -> Vector<T>{
var result = Vector<T>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(sin(o))
}
else {
result.append(nil)
}
}
return result
}
我得到“找不到接受提供的参数的罪的重载”
然后我尝试用MathemticType试图模仿我已经为运算符做的事情
(ArithmeticType的灵感来自IntegerAritmeticType源,通过命令点击导入swift找到的比我对我正在做的事情的了解更多)
==更新
如果我只为Double编写一个专门的函数
func sin(x: Vector<Double>) -> Vector<Double>{
var result = Vector<Double>()
for i in 0..<x.count() {
if let o = x[i] {
result.append(Darwin.sin(o))
}
else {
result.append(nil)
}
}
return result
}
它按预期工作.
所以这个问题可能会成为“我如何将其概括为Double和Float”?
编译器错误是因为您将sin()声明为MathematicType协议的方法,然后声明Double实现了MathematicType,但实际上并没有编写sin()方法.extension Double {
func sin(x: Double) -> Double {
return Darwin.sin(x)
}
}
我认为这不是你想要的,不是吗?你希望能够写下这个:
let myAngle = 3.14159 let sineValue = myAngle.sin()
如果是这种情况,您的协议和扩展将需要如下所示:
protocol MathematicType {
func sin() -> Self
}
extension Double : MathematicType {
func sin() -> Double {
return Darwin.sin(self)
}
}
