我遇到了一个无法解释的方法问题。以下是一些显示问题的测试代码:
aMethod()
根据Apple doco,我读过协议,泛型等。Base
应该接受任何符合Base
协议的对象。但它拒绝了我将它们投射到Extended
或func 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}}
如您所见,我想将几个参数约束为同一类型。因此,使用通用而不是仅指定基础。
答案 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
的实例符合Base
。 Base
或Extended
都不是有效的类型。
你在这里做的是使用没有它的力量的泛型......其中,恕我直言,没有意义。除非你能提供更现实的场景吗?