我有一个问题(可能是关于类型擦除)。想象一下以下场景:
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的抽象数据项,它有一个应该在选择单元格时调用的action属性。我的问题是如何创建DataItem对象数组,从此列表中选择一个项目(或迭代它)并调用相应的操作,该操作将打印UserItem的名称和DriverItem的许可证编号。但是在上面的实现中,编译器抱怨以下消息:项目列表只能是[Any]类型...
Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional
这样我就无法调用协议DataItem中声明的动作。我试图绕着类型擦除而不能理解它......
如果有人提出解决方案,会很高兴......
答案 0 :(得分:-1)
没有额外的要求并没有那么难:
struct UserItem {
let name: String
func action() {
print(name)
}
}
struct DriverItem {
let licenseNumber: String
func action() {
print(licenseNumber)
}
}
let data = UserItem(name: "Test")
let closure = { print("Some object data \(data.name)") }
let items = [
UserItem(name: "Dexter").action,
DriverItem(licenseNumber: "1234567890").action,
closure
]
items.forEach {
$0()
}
答案 1 :(得分:-1)
错误只是要求您向项目添加类型:
let items: Array<Any> = [
UserItem(name: "Dexter", action: { (item) in print(item.name)}),
DriverItem(licenseNumber: "1234567890", action: { (item) in print(item.licenseNumber)})
]
不确定这是否会导致更多错误,因为我不确定您是否可以在创建阵列时调用完成块。
修改
我认为你要做的是在调用变量时接听电话。这样做的方法是使用你已输入但未完成的get
,如下所示:
var licenseNumber: String {
get {
print("doSomething!")
return self.licenseNumber
}
}
数组会变成:
let items: Array<Any> = [
UserItem(name: "Dexter"),
DriverItem(licenseNumber: "1234567890")
]