【发布时间】:2018-12-15 03:27:14
【问题描述】:
我不知道如何进行强制转换,最终让我引入某种与泛型一起工作的活力。
下一段代码无法编译。它显示了这个错误:
无法使用类型参数列表调用“createContainer” '(FooProtocol)' 需要一个类型为 '(T)' 的参数列表
protocol FooProtocol {
func doSomething()
}
class Foo : FooProtocol {
func doSomething() {}
}
class Container<T : FooProtocol> {
let someDataConformingFooProtocol : T
init(someDataConformingFooProtocol : T) {
self.someDataConformingFooProtocol = someDataConformingFooProtocol
}
}
class AllTogether {
init () {
createContainer(Foo()) //So far, so good
let foo2Mask : AnyObject = Foo()
if let foo2MaskChecked = foo2Mask as? FooProtocol {
createContainer(foo2MaskChecked)
//ERROR: Cannot invoke 'createContainer' with an argument list of type '(FooProtocol)'
//Expected an argument list of type '(T)'
}
}
func createContainer<T : FooProtocol>(data: T){
Container<T>(someDataConformingFooProtocol: data)
}
}
这真的是预期的行为吗?因为我个人无法理解编译器在抱怨什么或为什么抱怨它。
合适的演员阵容是什么?如果不引用具体类,我的意思是不是这样的:
if let foo2MaskChecked = foo2Mask as? Foo
谢谢!
【问题讨论】:
-
这与类型差异有关。阅读以下内容:nomothetis.svbtle.com/type-variance-in-swift
-
我明白了。帖子的最后一个例子说明了同样的问题。似乎目前没有解决方案。谢谢!
-
@MikePollard 你能解释一下方差是如何在这里起作用的吗?我们不会试图将
Container<T>冒充为Container<FooProtocol>;我们所尝试的只是将一些U: FooProtocol传递给带有签名T: FooProtocol的方法。直觉上,U和T统一了,所以一切都应该很好。我错过了什么? -
有些日子,我想念 Scala。
-
FWIW,我认为类协议在这里应该有所帮助,但没有。 See this follow-up question.
标签: swift