【发布时间】:2019-01-24 19:13:18
【问题描述】:
我有一个将两个类作为参数的函数。我希望第一个是 NSObject 的子类(到目前为止非常简单),第二个是子类或与另一个相同的类 - 我该如何表达?
class MyClass: NSObject {}
class MySubClass: MyClass {}
myFunction(MyClass.Type, MySubClass.Type)
MyFunction 定义如下:
func myFunction<T: NSObject>(param1: T.Type, param2: T.Type)
不幸的是,因为 MyClass 和 MySubClass 不一样(我对 myFunction 的定义希望它们完全相同),所以 '(MyClass.Type, MySubClass.Type)' 的调用错误不能转换为'(MyClass.Type, MyClass.Type)'.
如何表达 myFunction 的第二个参数的类型不必与第一个相同,而只是 __kindof,就像在 Objective-C 中编写的那样?
编辑:
看来,我的问题并不清楚。
以下是不够的:
func myFunction<T:NSObject,U:NSObject>(param1: T.Type, param2: U.Type)
...因为它允许我以 myFunction(param1: MyClass.Type, param2: AnotherClass.Type) 的形式调用它,而 AnotherClass 定义为 class AnotherClass : NSObject。在这种情况下,AnotherClass 不在 MyClass 的继承层次结构中。
这就是为什么我给出了 __kindof 的例子,它表达了(在 ObjC 中)——即协变泛型。
【问题讨论】:
-
有趣,我希望
func myFunction<T:NSObject,U:T>(param1: T.Type, param2: U.Type)可以工作,因为T保证是一个类类型,但它会导致错误Inheritance from non-protocol, non-class type 'T'。 Similar question,但没有答案。 -
func myFunction<T:MyClass,U:MyClass>(param1: T.Type, param2: U.Type)? -
@DávidPásztor 是的,这太糟糕了。出于某种原因,每次我尝试使用 Swift 时,我最终要么在类型系统上走得太远,要么在其中发现了一个错误……在你看来,这属于哪种情况?
-
@Perceval 不确定这是一个错误还是一个尚未实现的功能......在这种情况下,编译器肯定能够推断出
T是一个类,因为它继承自另一个班级。我链接的另一个问题是一个更难破解的问题,因为编译器没有信息可以推断出T是一个类或协议类型 -
对于任何对此问题感兴趣的人,我为此创建了一个 Swift 编译器错误:SR-9780 以获得官方答案,说明这实际上是一个错误还是只是当前类型系统的一个缺点/编译器。