7

我有一个使用关联类型的协议,例如:

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])
}

我得到错误:

Protocol 'Populatable' 只能用作通用约束,因为它具有 Self 或关联的类型要求

测试对象是否符合可填充协议的正确方法是什么?

注意:尝试此操作所需的所有代码都包含在问题中,只需将代码块复制到操场上即可。

4

2 回答 2

0

正如错误所说,您不能在此处将其转换为 Populatable 。我认为正确的方法是将其转换为 EventRowType。

if let rowController = self.table.rowControllerAtIndex(i) as? EventRowType {

而且您已经测试了“EventRowType”类符合“Populatable”协议。因为如果 EventRowType 没有名为“populate”的函数,swift 编译器会说,

类型“EventRowType”不符合协议“Populatable”

于 2015-05-04T16:01:26.907 回答
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)
    }
}

您只需要为您添加的每个可填充类扩展它。

于 2015-05-04T23:56:39.537 回答