In Swift, how to generically limit function to types that understand T + T

前端 未结 3 506
孤独总比滥情好
孤独总比滥情好 2021-01-17 13:55

I would like to have a generic function that can use the plus operator on two values.

class funccalc {
    func doAdd(x:T,y:T) -> T {
        ret         


        
相关标签:
3条回答
  • 2021-01-17 14:22

    Have you tried using the protocol AdditiveArithmetic?

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

    Looks like thats exactly what you are looking for. That protocol has the method:

    static func + (Self, Self) -> Self

    Using your that protocol your method becomes:

    class funccalc {
        func doAdd<T: AdditiveArithmetic>(x:T,y:T) -> T {
            return x + y
        }
    }
    
    0 讨论(0)
  • 2021-01-17 14:29

    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...
    
    0 讨论(0)
  • 2021-01-17 14:35

    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.

    0 讨论(0)
提交回复
热议问题