在Swift中,如何将函数泛化为理解T + T的类型

时间:2014-06-12 00:45:41

标签: generics swift

我希望有一个泛型函数,可以在两个值上使用加号运算符。

class funccalc {
    func doAdd<T>(x:T,y:T) -> T {
        return x + y
    }
}
let a = funccalc()
println(a.doAdd(1, y: 4))
println(a.doAdd(23.54, y:200))

我在return x + y

上收到错误消息

我唯一的选择是遵循此答案中的建议:https://stackoverflow.com/a/24047239/67566,并创建我自己的协议IntString将定义运营商?

3 个答案:

答案 0 :(得分:12)

您可能对其他函数也有类似的需求,并且为所有整数和浮点类型(或其他&#34;可汇总和#34;事物)实现它们会导致大量代码重复。

一个部分解决方案,特别是+, - ,*,/,%是要求符合IntegerArithmeticType协议:

func example<T: IntegerArithmeticType>(x: T, y: T) -> T { return x + y }
println(example(40, 2)) // --> 42

这不适用于浮点类型,因为它们不实现在_IntegerArithmeticType协议中定义的溢出操作,IntegerArithmeticType继承自。

但是,为特定的全局定义的运算符函数一致性扩展类型并不像#34;烦人的&#34;你可能会想:

protocol Summable { func +(lhs: Self, rhs: Self) -> Self }

extension Int: Summable {}
extension Double: Summable {}
extension String: Summable {}
// extension for any other types... you are in full control!

你这样做一次,然后永远你可以在你的代码中使用Summable:

func example<T: Summable>(x: T, y: T) -> T { return x + y }

println( example("4", "2") ) // --> 42

确实,正如@connor所指出的,这相当于你提到的@ Jean-PhilippePellet的答案。

答案 1 :(得分:6)

你应该按照建议的答案去做。创建一个供您使用的协议,并扩展您要使用它的所有类。然后确保T在方法签名中实现该协议。

您无法使用&#34;可添加的&#34;协议,因为swift中没有一个。 swift库实际上为每个有效的加法操作创建了一个函数+。按住Command键点击Int之类的内容,查看所有这些内容的定义。它看起来像这样:

//....
func +(lhs: Int8, rhs: Int8) -> Int8
func +(lhs: UInt16, rhs: UInt16) -> UInt16
func +(lhs: Int16, rhs: Int16) -> Int16
func +(lhs: UInt32, rhs: UInt32) -> UInt32
func +(lhs: Int32, rhs: Int32) -> Int32
//etc...

答案 2 :(得分:2)

您是否尝试过使用协议AdditiveArithmetic

https://developer.apple.com/documentation/swift/additivearithmetic

看起来就是您要找的东西。该协议具有以下方法:

static func + (Self, Self) -> Self

使用该协议,您的方法将变为:

class funccalc {
    func doAdd<T: AdditiveArithmetic>(x:T,y:T) -> T {
        return x + y
    }
}