我正在尝试创建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) } }