我在声明数组并使用许多不同的通用项对其进行初始化时遇到问题,同时在通用支持下分别使用这些项。让我们来看一下:
protocol Item {
associatedtype ValueType: Any
var value: ValueType? { get set }
}
class ItemClass<T: Any>: Item {
typealias ValueType = T
var value: ValueType?
}
let intItem = ItemClass<Int>()
let stringItem = ItemClass<String>()
let array: [ItemClass<Any>] = [intItem, stringItem]
// Iterate over items and use `value` property as Any?
for item in array {
let val: Any? = item.value
// do something with val
}
// Individual usage with generic types support
let intValue: Int? = intItem.value
let stringValue: String? = stringItem.value
为什么这样的数组声明中有错误:
Cannot convert value of type 'ItemClass<Int>' to expected element type 'ItemClass<Any>'
答案 0 :(得分:1)
这整个方法都是不正确的,您可以通过使用代码看到这一点:
function App() {
// […]
}
_.extend(App.prototype, {
method1: function() {}
method2: function() {}
});
在“用val做某事”中,您可能会做什么? // Iterate over items and use `value` property as Any?
for item in array {
let val: Any? = item.value
// do something with val
}
上没有方法。如果您要执行Any
之类的操作,那么您已经破坏了类型的全部要点,因为您的意思不是“任何”。您的意思是“我知道的一些类型列表”。如果要“我知道的一些类型列表”,那么它是一个带有关联数据的枚举,而不是带有关联类型的协议。
as? T
如果,另一方面,如果您的意思确实是“任何类型”,那么您就无法将它们放入集合中,而无需将值隐藏在一个没有任何关于该类型的信息的框中(即“一种类型的橡皮擦”)。您需要哪些取决于您的实际用例。没有一个答案。它将由您要如何使用这些数据来驱动。
但是如果您非常需要enum Item {
case string(String)
case int(Int)
var stringValue: String? {
guard case .string(let value) = self else { return nil }
return value
}
var intValue: Int? {
guard case .int(let value) = self else { return nil }
return value
}
}
let intItem = Item.int(4)
let stringItem = Item.string("value")
let array: [Item] = [intItem, stringItem]
// Iterate over items and use `value` property as Any?
for item in array {
switch item {
case let .string(value): break // Do something with string
case let .int(value): break // Do something with int
}
}
// Individual usage with generic types support
let intValue: Int? = intItem.intValue
let stringValue: String? = stringItem.stringValue
,则说明您做错了事。