我无法弄清楚如何进行演员表演,这会让我最终引入一些与泛型一起工作的动态。
下一段代码无法编译。它显示了这个错误:
无法调用' 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
谢谢!
答案 0 :(得分:0)
归结为@Hamish在评论中提到的T: FooProtocol
和FooProtocol
之间的区别。
当我有这样的功能时:
func foo(_ i: FooProtocol)
我要使用类型为FooProtocol
的实例,因此我可以传入一个符合FooProtocol
或它的类型为FooProtocol
的值。这类似于子类化,在子类化中,您可以将SuperClass
和SubClass
都传递到SuperClass
中。
但是,如果您具有这样的功能:
func foo<T>(_ i: T) where T: FooProtocol
我可以传入任何符合FooProtocol
的类型,但是由于FootProtocol
不符合自身,因此您不能将其传入。
因此,在您的问题中,您尝试传递类型FooProtocol
,其中类型必须符合与FooProtocol
。您可以通过以下方法解决此问题:
class Container {
let someDataConformingFooProtocol: FooProtocol
init(someDataConformingFooProtocol: FooProtocol) {
self.someDataConformingFooProtocol = someDataConformingFooProtocol
}
}
// Later
func createContainer(data: FooProtocol){
Container(someDataConformingFooProtocol: data)
}