无法在Swift中创建符合协议类型的数组 [英] Can't create an Array of types conforming to a Protocol in Swift
问题描述
我有以下协议和符合该协议的类:
I have the following protocol and a class that conforms to it:
protocol Foo{
typealias BazType
func bar(x:BazType) ->BazType
}
class Thing: Foo {
func bar(x: Int) -> Int {
return x.successor()
}
}
当我尝试创建foos数组时,出现一个奇怪的错误:
When I try to create an Array of foos, I get an odd error:
var foos: Array<Foo> = [Thing()]
协议Foo只能用作一般约束,因为它具有 自我或相关类型要求.
Protocol Foo can only be used as a generic constraint because it has Self or associated type requirements.
好,因此只有在具有关联的类型要求(确实如此)的情况下才可以使用它,但是由于某种原因,这是一个错误? WTF?!
OK, so it can only be used if it has an associated type requirement (which it does), but for some reason this is an error?? WTF?!
我不确定我是否完全理解编译器要告诉我的内容...
I'm not sure I fully understand what the compiler is trying to tell me...
推荐答案
比方说,如果我们可以将Thing
的实例放入数组foos
,会发生什么?
Let's say, if we could put an instance of Thing
into array foos
, what will happen?
protocol Foo {
typealias BazType
func bar(x:BazType) -> BazType
}
class Thing: Foo {
func bar(x: Int) -> Int {
return x.successor()
}
}
class AnotherThing: Foo {
func bar(x: String) -> String {
return x
}
}
var foos: [Foo] = [Thing()]
因为AnotherThing
也符合Foo
,所以我们也可以将其放入foos
.
Because AnotherThing
conforms to Foo
too, so we can put it into foos
also.
foos.append(AnotherThing())
现在,我们从foos
中随机抓取一个foo
.
Now we grab a foo
from foos
randomly.
let foo = foos[Int(arc4random_uniform(UInt32(foos.count - 1)))]
然后我要调用方法bar
,你能告诉我应该向bar
发送字符串还是整数?
and I'm going to call method bar
, can you tell me that I should send a string or an integer to bar
?
foo.bar("foo")
或foo.bar(1)
雨燕不能.
因此它只能用作一般约束.
So it can only be used as a generic constraint.
什么情况下需要这样的协议?
What scenario requires a protocol like this?
示例:
class MyClass<T: Foo> {
let fooThing: T?
init(fooThing: T? = nil) {
self.fooThing = fooThing
}
func myMethod() {
let thing = fooThing as? Thing // ok
thing?.bar(1) // fine
let anotherThing = fooThing as? AnotherThing // no problem
anotherThing?.bar("foo") // you can do it
// but you can't downcast it to types which doesn't conform to Foo
let string = fooThing as? String // this is an error
}
}
这篇关于无法在Swift中创建符合协议类型的数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!