Generics type constraint vs inheritance

前端 未结 1 422
挽巷
挽巷 2021-01-22 11:20

Is there a difference between these two function declarations?

func doSomething(controller: T) {...}

vs.

<         


        
相关标签:
1条回答
  • 2021-01-22 11:26

    They are different, but in the way you are using them, they amount to pretty much exactly the same result.

    The difference is that when you call the generic version, the compiler sets T statically to be whatever type is passed in as the argument. When calling methods on that argument, this makes almost no difference – either way the calls on its methods will be dynamically dispatched, and you can't touch any parts of T that aren't guaranteed to be available from the constraint.

    But suppose you made a change to this method to not just take an argument, but also return one, of the same type:

    // T here will take the type of whatever is going in/out of the function
    // be that UIViewController or a subtype of it
    func doSomethingGenerically<T: UIViewController>(controller: T) -> T {  
        // some logic that results in a new controller being returned
    }
    
    // here the return type is fixed to be UIViewController
    func doSomethingViaBaseClass(controller: UIViewController) -> UIViewController {  
        // some logic that results in a new controller being returned
    }
    

    Now, suppose you had a subclass of UIViewController that you were passing in, like so:

    let subClass: MyUIViewController = ...
    
    let controller1 = doSomethingGenerically(subClass)
    
    let controller2 = doSomethingViaBaseClass(subClass)
    

    Here, the type of the variable controller1 will be MyUIViewController, because that is what was passed in to the function so that is what T is. But the type of the variable controller2 will be UIViewController because that is the fixed type that doSomethingViaBaseClass returns.

    Note, this doesn't mean the object they reference will be different - that depends on what the body of the function implements. It's just the type of the variables referring to it that will change.

    There are other subtle differences but this is the main one to know about. In the case of structs, however, there are more differences worth noting. As it happens I wrote an article about them yesterday that might help.

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