数组和单个项目通用支持的Swift通用问题

时间:2018-12-19 12:41:30

标签: swift generics

我在声明数组并使用许多不同的通用项对其进行初始化时遇到问题,同时在通用支持下分别使用这些项。让我们来看一下:

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>'

1 个答案:

答案 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 ,则说明您做错了事。