'In Swift, how to generically limit function to types that understand T + T
I would like to have a generic function that can use the plus operator on two values.
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))
I get an error on return x + y
Is my only option to follow the suggestion in this answer: https://stackoverflow.com/a/24047239/67566, and create my own protocol as Int and String would define the operator?
Solution 1:[1]
You may have a similar need for other functions too and implementing them for all integer and floating point types (or other "summable" things) would cause massive code duplication.
One partial solution, specifically for +, -, *, /, % is to require conformance to IntegerArithmeticType protocol:
func example<T: IntegerArithmeticType>(x: T, y: T) -> T { return x + y }
println(example(40, 2)) // --> 42
This does not apply to floating point types because they do not implement overflow operations defined in _IntegerArithmeticType protocol, which IntegerArithmeticType inherits from.
However, extending types for a specific globally defined operator function conformance is not as "annoying" as you might think:
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!
You do this once, then forevermore you can use Summable in you code:
func example<T: Summable>(x: T, y: T) -> T { return x + y }
println( example("4", "2") ) // --> 42
Indeed, and as @connor pointed out, this is equivalent to @Jean-PhilippePellet's answer you mentioned.
Solution 2:[2]
You should do as that answer suggested. Create a protocol for your use and extend all of the classes that you want to use it. Then make sure T implements that protocol in your method signature.
You can't use an "addable" protocol because there isn't one in swift. The swift library actually creates a function + for each valid addition operations. Command-click on something like Int to see where all of these are defined. It will look something like this:
//....
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...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Connor |
