我有一个使用关联类型的协议,如下:
protocol Populatable {
typealias T
func populateWith(object: T)
}
以及实现该协议的类:
class DateRowType: Populatable {
func populateWith(object: NSDate) {
print(object.description)
}
}
class StringRowType : Populatable {
func populateWith(object: String) {
print(object)
}
}
但是当我尝试投射或测试一致性时,像这样:
let drt = DateRowType()
let srt = StringRowType()
let rowTypes = [drt, srt]
let data = [NSDate(), "foo"]
for (i, p: Populatable) in enumerate(rowTypes) {
p.populateWith(data[i])
}
我收到错误:
协议'可推广'只能用作通用约束,因为它具有Self或关联类型要求
测试对象是否符合Populatable协议的正确方法是什么?
注意:尝试此操作所需的所有代码都包含在问题中,只需将代码块复制到操场中即可。
答案 0 :(得分:0)
正如错误所说,你不能把它投到Populatable这里。我认为正确的方法是将其转换为EventRowType。
if let rowController = self.table.rowControllerAtIndex(i) as? EventRowType {
你已经测试了那个' EventRowType'班级符合'可推广'协议。因为如果EventRowType没有名为' populate'的函数,swift编译器说,
输入' EventRowType'不符合协议' Populatable'
答案 1 :(得分:0)
我认为除非可能通过使用AnyObject并在每个populateWith函数中测试参数的类,否则你将无法全程通用。
但这会奏效:
for (i, p) in enumerate(rowTypes) {
if let dateRow = p as? DateRowType {
dateRow.populateWith(data[i] as! NSDate)
}
else if let stringRow = p as? StringRowType {
stringRow.populateWith(data[i] as! String)
}
}
您只需要为添加的每个Populatable类扩展它。