这两个函数声明之间有区别吗?
func doSomething<T: UIViewController>(controller: T) {...}
VS
func doSomething(controller: UIViewController) {...}
在Apples Swift programming language本书的类型约束语法部分中,有以下代码示例:
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
// function body goes here
}
有了这个描述:
上面的假设函数有两个类型参数。第一个类型参数T有一个类型约束,要求T是SomeClass的子类。 ...
那么在哪种情况下使用上述通用功能会更好?
答案 0 :(得分:5)
它们不同,但在你使用它们的方式上,它们几乎完全相同。
不同之处在于,当您调用泛型版本时,编译器将T
静态设置为作为参数传入的任何类型。在对该参数调用方法时,这几乎没有任何区别 - 无论是对其方法的调用都将动态调度,并且您不能触及T
的任何不保证可从约束中获得的部分。
但是假设您对此方法进行了更改,不仅仅是接受一个参数,而且返回一个类型相同:
// 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)
此处,变量controller1
的类型将为MyUIViewController
,因为这是传递给函数的内容,因此T
是controller2
。但变量UIViewController
的类型将为doSomethingViaBaseClass
,因为这是{{1}}返回的固定类型。
注意,这并不意味着它们引用的对象将不同 - 这取决于函数体实现的内容。只是引用的变量的类型将会改变。
还有其他微妙的差异,但这是最需要了解的。然而,就结构而言,还有更多的差异需要注意。碰巧我昨天写了关于他们的an article,这可能有所帮助。