Generics type constraint vs inheritance

老子叫甜甜 提交于 2019-12-31 02:35:05

问题


Is there a difference between these two function declarations?

func doSomething<T: UIViewController>(controller: T) {...}

vs.

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

In Type Constraint Syntax section of the Apples Swift programming language book, there's this code sample:

func​ ​someFunction​<​T​: ​SomeClass​, ​U​: ​SomeProtocol​>(​someT​: ​T​, ​someU​: ​U​) {
    // function body goes here
}

with this description:

The hypothetical function above has two type parameters. The first type parameter, T, has a type constraint that requires T to be a subclass of SomeClass. ...

So in which cases is it better to use generic function described above?


回答1:


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.



来源:https://stackoverflow.com/questions/29284754/generics-type-constraint-vs-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!