【问题标题】:Swift covariant generic function : placeholder type is a subclass of anotherSwift协变泛型函数:占位符类型是另一个的子类
【发布时间】: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&lt;T:NSObject,U:NSObject&gt;(param1: T.Type, param2: U.Type) ...因为它允许我以 myFunction(param1: MyClass.Type, param2: AnotherClass.Type) 的形式调用它,而 AnotherClass 定义为 class AnotherClass : NSObject。在这种情况下,AnotherClass 不在 MyClass 的继承层次结构中。

这就是为什么我给出了 __kindof 的例子,它表达了(在 ObjC 中)——即协变泛型。

【问题讨论】:

  • 有趣,我希望func myFunction&lt;T:NSObject,U:T&gt;(param1: T.Type, param2: U.Type) 可以工作,因为T 保证是一个类类型,但它会导致错误Inheritance from non-protocol, non-class type 'T'Similar question,但没有答案。
  • func myFunction&lt;T:MyClass,U:MyClass&gt;(param1: T.Type, param2: U.Type) ?
  • @DávidPásztor 是的,这太糟糕了。出于某种原因,每次我尝试使用 Swift 时,我最终要么在类型系统上走得太远,要么在其中发现了一个错误……在你看来,这属于哪种情况?
  • @Perceval 不确定这是一个错误还是一个尚未实现的功能......在这种情况下,编译器肯定能够推断出 T 是一个类,因为它继承自另一个班级。我链接的另一个问题是一个更难破解的问题,因为编译器没有信息可以推断出T 是一个类或协议类型
  • 对于任何对此问题感兴趣的人,我为此创建了一个 Swift 编译器错误:SR-9780 以获得官方答案,说明这实际上是一个错误还是只是当前类型系统的一个缺点/编译器。

标签: swift generics


【解决方案1】:

这是你需要的还是不需要的?运行没有问题。

class MyClass: NSObject {}
class MySubClass: MyClass {}

func myFunction<T: NSObject>(param1: T.Type, param2: T.Type){
print("OK")
}
myFunction(param1: MyClass.self, param2: MySubClass.self as MyClass.Type)

myFunction(param1: type(of: MyClass()), param2: type(of: MySubClass()))

【讨论】:

  • 您仍然可以使用父类的两个实例调用该函数,但这并不能解决最初的问题。
【解决方案2】:

Swift 编译器目前不支持此功能。您可以在SR-5213 下跟踪此功能的实施状态。

根据一位 Apple 开发人员对此问题的评论,我不希望它很快发生:

老实说,我怀疑这不会很快从我们的实施者那里获得太大的吸引力,因为它不是一个非常常见的用例——价值增益并不能证明短期内所需的工作是合理的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-02
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多