Swift协议用作不接受相同协议实例的方法中的类型

时间:2017-02-16 03:16:48

标签: swift generics protocols

我遇到了一个无法解释的方法问题。以下是一些显示问题的测试代码:

aMethod()

根据Apple doco,我读过协议,泛型等。Base应该接受任何符合Base协议的对象。但它拒绝了我将它们投射到Extendedfunc aMethod2(_ instance:Base) {} aMethod2(anInstance) aMethod2(instanceOfBase) aMethod2(instanceOfExtended) 的两种情况。

任何人都能解释一下吗?

此外:

instance

工作正常,差异似乎是Base参数是基于<T:Base>还是func addViewController<T:ModelObject>(_ stack:inout [UIViewController], object:T?, controller:DetailsViewController<T>?, storyboardId:String) {... (<1}}。

对于任何质疑为什么我会在这里宣布通用的人。原始代码看起来像这样:

{{1}}

如您所见,我想将几​​个参数约束为同一类型。因此,使用通用而不是仅指定基础。

2 个答案:

答案 0 :(得分:2)

T是对具体类型的约束

<T:Base>是占位符类型T的约束。 T必须是符合Instance协议的具体类型(类,枚举或结构,如Base)。占位符类型T不能是Base协议。

必须使用在编译时符合aMethod<T:Base>(:)协议的类型的变量调用

Base。无法使用仅知道aMethod<T:Base>(:)类型的变量调用Base

以下代码行实例化了一个名为anInstance的变量,该变量的结构类型为Instance

let anInstance = Instance()

aMethod(anInstance)编译因为anInstance具有符合Instance协议的具体类型Base

以下代码行实例化了一个名为instanceOfBase的变量,其协议类型为Base

let instanceOfBase: Instance = anInstance as Base

aMethod(instanceOfBase)无法编译,因为instanceOfBase不是符合Base协议的具体类型。它的协议类型为Base

这是另一个未能说明问题的片段。在这种情况下,base参数仅为协议类型Base

func aMethod(base: Base) {
    aMethod(base) // Cannot invoke 'aMethod' with an argument list of type '(Base)'
}

答案 1 :(得分:1)

嗯,我真的不明白你为什么要这样做。

让我们说:

  • 您希望aMethod接受符合Base协议的任何实例,然后您可以func aMethod(_ instance: Base) {}
  • 您希望在函数内部保留类型信息,然后使用泛型方法,但传递协议的具体实现的实例。

请注意,func aMethod<T:Base>(_ instance:T) {}表示期望 type T的实例符合BaseBaseExtended都不是有效的类型

你在这里做的是使用没有它的力量的泛型......其中,恕我直言,没有意义。除非你能提供更现实的场景吗?