Ответ 1
Скажем, если бы мы могли поместить экземпляр 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())
Теперь мы произвольно получаем a Foo
из foos
.
let foo = foos[Int(arc4random_uniform(UInt32(foos.count - 1)))]
и я собираюсь вызвать метод bar
, можете ли вы сказать мне, что я должен отправить строку или целое число в bar
?
foo.bar("foo")
или foo.bar(1)
Swift не может.
Поэтому его можно использовать только как общее ограничение.
Какой сценарий требует такого протокола?
Пример:
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
}
}