Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Swift 使用相关类型测试协议一致性_Swift_Generics_Swift Protocols - Fatal编程技术网

Swift 使用相关类型测试协议一致性

Swift 使用相关类型测试协议一致性,swift,generics,swift-protocols,Swift,Generics,Swift Protocols,我有一个使用关联类型的协议,例如: protocol Populatable { typealias T func populateWith(object: T) } 以及实现该协议的类: class DateRowType: Populatable { func populateWith(object: NSDate) { print(object.description) } } class StringRowType : Populata

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

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])
}
我得到一个错误:

协议“Populateable”只能用作一般约束,因为它具有自身或关联的类型要求

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


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

正如错误所述,您无法在此处将其强制转换为populateable。我认为正确的方法是将其转换为EventRowType

if let rowController = self.table.rowControllerAtIndex(i) as? EventRowType {
您已经测试过“EventRowType”类符合“Populatable”协议。因为如果EventRowType没有名为“populate”的函数,swift编译器会说

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


我不认为您将能够完全通用化,除非可能使用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)
    }
}

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

是的,不幸的是,我希望它是通用的,并与实现可填充协议的多行类型一起工作。有办法吗?我想没有办法。如果希望它是泛型的,则必须在编译时为编译器指定类型信息。是否有方法对协议或声明进行注释以通知编译器?我希望有其他行类型类将其他类型作为填充函数的参数。目前,事件数组是异构的,但将来可能包含许多实现可填充协议的类型。每行将由不同的类型填充,因此我希望我的协议是通用的,以便一行可以实现为填充(对象:事件),另一行可以实现为填充(对象:团队),等等。如果不是泛型的,我必须让协议使用populate(object:AnyObject),这就消除了使用Swift的许多乐趣。populate不接受populate,它包含在populate协议中。Populate在另一个类上定义了一个方法,在本例中是用作WKInterfaceTable控制器的NSObject。此处有其他注释和答案,但已被海报删除。我曾说过,创建泛型函数是解决方案,但事实并非如此。我还需要输入别名。我将发布一个Swift游乐场来澄清。谢谢,我希望这将由泛型自动处理。我疯了吗?或者这种事情在Java/C中可能发生吗?像你一样,我本以为它应该与泛型一起工作,但我没有太多地使用它们。