genericstypes约束与inheritance

这两个函数声明有没有区别?

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

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

在Apples Swift编程语言书的types约束语法部分,有这样的代码示例:

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

与此描述:

上面的假设函数有两个types参数。 第一个types参数T有一个types约束,它要求T是SomeClass的子类。 …

那么在哪种情况下最好使用上面描述的通用函数呢?

它们是不同的,但是按照你使用它们的方式,它们的结果几乎完全相同。

不同的是,当你调用通用版本时,编译器将静态地设置T作为参数传入的任何types。 当调用该参数的方法时,这几乎没有什么区别 – 调用方法上的调用的任何一种方式都将被dynamic分配,并且不能触及任何不能保证从约束中可用的T部分。

但是,假设您对此方法进行了更改,以便不仅接受参数,还返回相同types的参数:

 // 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 } 

现在,假设你有一个你传入的UIViewController的子类,如下所示:

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

在这里,variablescontroller1的types将是MyUIViewController ,因为那是传递给函数的东西,所以T就是这个东西。 但是,variablescontroller2的types将是UIViewController因为这是doSomethingViaBaseClass返回的固定types。

请注意,这并不意味着它们引用的对象将会不同 – 这取决于函数的主体实现。 这只是引用它的variables的types将会改变。

还有其他细微的差异,但这是主要的了解。 但是在结构方面,还有更多值得注意的地方。 碰巧我昨天写了一篇关于他们的文章 ,可能有帮助。