我想为实现这些协议的对象构建协议映射。然后我希望能够获得给定协议的实现。
这是我到目前为止所得到的:
<iron-pages>
我可以这样称呼它:
class Services {
var map = NSMapTable(keyOptions: .CopyIn, valueOptions: .WeakMemory)
func register<T>(type: T, target: AnyObject) {
map.setObject(target, forKey: String(type))
}
func get<T>(type: T) -> AnyObject {
guard let target = map.objectForKey(String(type)) else {
fatalError("Not registered")
}
return target
}
}
这太棒了。但是当我想要检索它时:
protocol Foo {
func qux()
}
class Bar: Foo {
func qux() {}
}
services.register(Foo.self, target: Bar())
...上面一行会产生错误:
Foo.swift:12:34:无法将调用结果类型'AnyObject'转换为预期类型'Foo'
如何指定泛型函数let foo: Foo = services.get(Foo.self)
返回实现get
中引用的协议的对象?
我想避免不得不接听电话。
答案 0 :(得分:1)
我不确定这是否符合你的目的,但你可以这样写:
class Services {
var map = NSMapTable(keyOptions: .CopyIn, valueOptions: .WeakMemory)
func register<T>(type: T.Type, target: T) {
guard let object = target as? AnyObject else {
fatalError("Cannot register")
}
map.setObject(object, forKey: String(type))
}
func get<T>(type: T.Type) -> T {
guard let target = map.objectForKey(String(type)) as? T else {
fatalError("Not registered")
}
return target
}
}
答案 1 :(得分:0)
我知道你想避免贬低我,但我认为你应该使用:
if let foo: Foo = services.get(Foo.self) as? Foo {
}
因为在您的情况下,protocol Foo: class
无效。
答案 2 :(得分:0)
如果让get
返回泛型类型,你甚至不需要类型参数,因为你已经拥有它:
func get<T>() -> T {
guard let target = map.objectForKey(String(T.self)) else {
fatalError("Not registered")
}
return target as! T // or you could make the return type an Optional if you want to allow getting a service that wasn't registered.
}
然后你可以像这样使用它:
let foo: Foo = services.get()