我想知道我在这段代码中是否有一些简单的东西,或者它只是混合了一些阻止我做什么的Swift技巧我想要。
我允许实现Foo
协议的类型包含任何类型的entity
属性,只要它符合StringIdentifiable
:
protocol StringIdentifiable {
var id: String? { get }
}
protocol Foo: class {
associatedtype AnyStringIdentifiable: StringIdentifiable
var entity: AnyStringIdentifiable? { get set }
}
从Swift 3.1开始,这个"任何类型"部分wouldn't be possible如果不使用associatedtype
。接下来,我们说我有另一个需要Foo
属性的协议。但是,Foo
是通用的,因此您可能知道我们无法做到这一点,因为"通用协议只能用作通用约束" 。为了避免类型擦除混乱,我决定在我的第二个协议中使用另一个associatedtype
并且编译器没有抱怨:
protocol Bar {
//var foo: Foo { get set } // can't do because Foo is generic
associatedtype AnyFoo: Foo
var foo: AnyFoo { get set }
}
但是现在,如果我尝试在foo
中设置内容,编译器会抱怨:
extension Bar {
func setEntity(_ entity: StringIdentifiable) {
foo.entity = entity
}
}
错误是无法分配类型' StringIdentifiable'的值输入' _?'
注意:这个问题的代码可以在游乐场测试。
答案 0 :(得分:3)
你可以这样做
//: Playground - noun: a place where people can play
import Cocoa
protocol StringIdentifiable {
var id: String? { get }
}
protocol Foo: class {
associatedtype AnyStringIdentifiable: StringIdentifiable
var entity: AnyStringIdentifiable? { get set }
}
protocol Bar {
//var foo: Foo { get set } // can't do because Foo is generic
associatedtype AnyFoo: Foo
var foo: AnyFoo { get set }
}
extension Bar {
func setEntity(_ entity: AnyFoo.AnyStringIdentifiable) {
foo.entity = entity
}
}
在栏内,您可以使用AnyFoo.AnyStringIdentifiable
确保在设置foo.entity
时类型正确,因为foo.entity
属于AnyFoo.AnyStringIdentifiable
类型。