我有一个问题(也许关于类型擦除)。想象一下以下情形:符合相关协议的对象的快速收集
public protocol DataItem {
associatedtype T
var action: ((_ item: T) -> Void)? {get}
}
struct UserItem: DataItem {
typealias T = UserItem
// Custom Properties
let name: String
// Protocol: DataItem
let action: ((T) -> Void)?
}
struct DriverItem: DataItem {
typealias T = DriverItem
// Custom Properties
let licenseNumber: String
// Protocol: DataItem
let action: ((T) -> Void)?
}
let items = [
UserItem(name: "Dexter", action: { (item) in print(item.name)}),
DriverItem(licenseNumber: "1234567890", action: { (item) in print(item.licenseNumber)})
]
items.forEach {
$0.action?($0)
}
我有一个DataItem的这是一个UITableViewCell一个抽象的数据项,其中有一个动作属性选择单元格时被调用。我的问题是如何创建一个DataItem对象数组,从这个列表中选择一个项目(或迭代它)并调用相应的操作,它将打印UserItem的名称和DriverItem的许可证编号。但是,与编译器上面实现以下消息抱怨说,项目清单只能是类型[任何] ...
Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional
这样我可以不叫在协议的DataItem声明的行动。我试图环绕型擦除我的头,但不明白它尚未......如果有人想出了一个解决方案
会很高兴......
这看起来有点怪异,你'associatedtype'在'UserItem'(/'DriverItem /)'是'UserItem'(/'DriverItem /)本身,这意味着_instance_close'action'采用与拥有它的实例相同类型的单个参数。这是否如预期那样,例如给定的'UserItem'实例是对'UserItem'的_another_实例执行一个动作?我希望这个动作可以在实例本身而不是辅助外部实例上执行,但也许这是一个预期的设计选择。无论如何,如果是这样,你可以放弃'associatedtype',只需使用'Self'而不是'T'。 – dfri
它与UIControls中的目标/动作一样,旨在为操作方法中的发件人提供服务。发件人是项目本身。我希望能够在操作方法中使用具体类型的功能(如name和licenseNumber) - 你知道吗?重要的是,这些项目只存在于一个DataSource对象内,它不知道具体的类型。这就是为什么我不能直接访问具体类型的功能。我会尽快尝试你的方法。非常感谢:-) – blackjacx
Arg ....使用Self而不是T行为相同:'Protocol'DataItem'只能用作通用约束,因为它具有Self或关联类型要求。由于这种行为类型橡皮擦被写入。但我不明白如何正确地做到这一点......任何人的想法? – blackjacx