我试图创建一个委托协议来实现一个传递泛型类型数组的函数。我尝试了几种组合,但似乎没有一种组合。
这是我达成的最近似的事情。这是协议:
protocol APIControllerProtocol {
typealias T
func didReceiveAPIResults(results: [T])
}
这是委托人对象:
class APIController<U:APIControllerProtocol> {
typealias ElementType = U
var delegate: ElementType?
init(delegate: ElementType){
self.delegate = delegate
}
func getAPIResults(){
// Perform some action before delegation
// "results" is an Array of dictionaries got from NSJSONSerialization
self.delegate?.didReceiveAPIResults(results.map{dict in Album(json:dict)})
}
}
但是,最后一行会收到此错误:&#34;专辑无法转换为U.T&#34;
&#34;相册&#34;是用于返回结果的模型对象。
我做错了什么?
修改
在Mike S advice之后,我已经将协议方法didReceiveAPIResults
作为通用函数,并指定了T
在委托中的内容。但是,当接收并将类型T的参数分配给委托中的属性时,我得到错误:&#34; T与T&#34;
class TestDelegate: APIControllerProtocol {
typealias T = Album
var albums:[T] = [T]()
func didReceiveAPIResults<T>(results: [T]) {
// ...
self.albums = results //ERROR: "T is not identical to T"
}
}
答案 0 :(得分:1)
didReceiveAPIResults
中的APIControllerProtocol
声明需要是通用函数,以便将通用类型T
正确传递给它。
protocol APIControllerProtocol {
typealias T
func didReceiveAPIResults<T>(results: [T])
}
注意:这意味着您的委托定义需要定义T
是什么:
class TestDelegate: APIControllerProtocol {
typealias T = Album
func didReceiveAPIResults<T>(results: [T]) {
// ...
}
}
更新:虽然上面的代码确实摆脱了原始错误,但事实证明它更像是一种解决方法,并没有真正解决问题的根源。 / em>的
真正的问题似乎是编译器无法协调U.T
没有含糊不清的内容。这实际上很容易修复,我们只需要给它一个更精确的定义(注意where
定义中的APIController
子句):
protocol APIControllerProtocol {
typealias T
func didReceiveAPIResults(results: [T])
}
class APIController<U:APIControllerProtocol where U.T == Album> {
typealias ElementType = U
// ...
}
注意:我删除了之前添加到协议中的函数的<T>
;这不再需要了,最后会导致问题。
这样,TestDelegate
类按预期工作(您甚至不再需要typealias
):
class TestDelegate: APIControllerProtocol {
var albums: [Album]? = nil
func didReceiveAPIResults(results: [Album]) {
albums = results
}
}