我有以下协议和符合它的类:
protocol Foo{ typealias BazType func bar(x:BazType) ->BazType } class Thing: Foo { func bar(x: Int) -> Int { return x.successor() } }
当我尝试创建一个foos的数组时,我得到一个奇怪的错误:
var foos: Array<Foo> = [Thing()]
Protocol Foo can only be used as a generic constraint because it has
Self or associated type requirements.
好的,所以它只能被使用,如果它有一个关联的类型要求(它做),但由于某些原因这是一个错误? WTF?
我不知道我完全明白编译器试图告诉我什么
假设我们可以把一个Thing的例子放在数组foos中,会发生什么?
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中.
foos.append(AnotherThing())
现在我们从foos中随机抓取一个foo.
let foo = foos[Int(arc4random_uniform(UInt32(foos.count - 1)))]
我要调用方法栏,你能告诉我,我应该发送一个字符串或一个整数到bar吗?
foo.bar(“foo”)或foo.bar(1)
斯威夫特不能.
所以它只能用作一般的约束.
什么场景需要这样的协议?
例:
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 } }