泛型类型约束与继承
Generics type constraint vs inheritance
这两个函数声明有区别吗?
func doSomething<T: UIViewController>(controller: T) {...}
对比
func doSomething(controller: UIViewController) {...}
在 Apples Swift programming language 书中的 Type Constraint Syntax 部分中,有以下代码示例:
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
// function body goes here
}
具有以下描述:
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. ...
那么在哪些情况下使用上述泛型函数更好?
它们是不同的,但就您使用它们的方式而言,它们的结果几乎完全相同。
不同之处在于,当您调用泛型版本时,编译器会将 T
静态设置为作为参数传入的任何类型。在该参数上调用方法时,这几乎没有区别——无论哪种方式,对其方法的调用都将被动态调度,并且您不能触及 T
中不能保证从约束中可用的任何部分.
但是假设您对此方法进行了更改,不仅接受一个参数,而且 return 一个相同类型的参数:
// 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
returns.
的固定类型
请注意,这并不意味着它们引用 的对象会有所不同——这取决于函数体实现的内容。只是 引用 的变量类型会发生变化。
还有其他细微差别,但这是需要了解的主要差别。然而,在结构的情况下,有更多值得注意的差异。碰巧我昨天写了 an article 关于他们的文章,这可能会有所帮助。
这两个函数声明有区别吗?
func doSomething<T: UIViewController>(controller: T) {...}
对比
func doSomething(controller: UIViewController) {...}
在 Apples Swift programming language 书中的 Type Constraint Syntax 部分中,有以下代码示例:
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
// function body goes here
}
具有以下描述:
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. ...
那么在哪些情况下使用上述泛型函数更好?
它们是不同的,但就您使用它们的方式而言,它们的结果几乎完全相同。
不同之处在于,当您调用泛型版本时,编译器会将 T
静态设置为作为参数传入的任何类型。在该参数上调用方法时,这几乎没有区别——无论哪种方式,对其方法的调用都将被动态调度,并且您不能触及 T
中不能保证从约束中可用的任何部分.
但是假设您对此方法进行了更改,不仅接受一个参数,而且 return 一个相同类型的参数:
// 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
returns.
请注意,这并不意味着它们引用 的对象会有所不同——这取决于函数体实现的内容。只是 引用 的变量类型会发生变化。
还有其他细微差别,但这是需要了解的主要差别。然而,在结构的情况下,有更多值得注意的差异。碰巧我昨天写了 an article 关于他们的文章,这可能会有所帮助。