Reputation: 46
I want to write a function that takes two values of the same type and returns the sum. My current approach is this:
protocol Summable {
static func +(lhs: Self, rhs: Self) -> Self
}
extension Int: Summable {}
extension String: Summable {}
extension Double: Summable {}
func sum<T: Summable>(_ obj1: T, with obj2: T) -> T {
return obj1 + obj2
}
print(sum(5, with: 4)) // 9
print(sum(5.5, with: 4.3)) // 9.8
print(sum("5", with: "4")) // 54
Is this the best that can be done or it can be improved?
Upvotes: 1
Views: 980
Reputation: 236458
If you need to make sure your type can be summed all you need to do is to constrain your generic type to additivearithmetic
If you need to support Strings, make it conform to AdditiveArithmetic but you will need to implement subtraction as well:
extension String: AdditiveArithmetic {
public static func -= (lhs: inout String, rhs: String) {
var set = Set(rhs)
lhs.removeAll{ !set.insert($0).inserted }
}
public static func - (lhs: String, rhs: String) -> String {
var set = Set(rhs)
return lhs.filter{set.insert($0).inserted}
}
public static var zero: String { "" }
}
func sum<T: AdditiveArithmetic>(_ lhs: T, with rhs: T) -> T {
lhs + rhs
}
func subtract<T: AdditiveArithmetic>(_ lhs: T, from rhs: T) -> T {
rhs - lhs
}
print(sum(5, with: 4)) // 9
print(sum(5.5, with: 4.3)) // 9.8
print(sum("5", with: "4")) // 54
print(subtract("5", from: "12345")) // "1234\n"
"12345" - "5" // "1234"
Upvotes: 1