我将继续我的旅程,去发现人们对斯威夫特仿制药的爱与恨,最终,我仍在努力克服一个根本性的缺陷:在数组中存储仿制药时(即使使用
fancy type erasure
),我仍然需要将数组中的结果值显式转换为已知类型,然后才能获取或设置数组中的属性。
我知道类型,但我似乎可以存储它的唯一方法是通过类的字符串名(因为你似乎无法创建类型数组)。也许有一种正确的方法来编码/解码类型,以便将其存储在数组中?我试过了
NSClassFromString
,但没走多远。
以下是一个游乐场,展示了这一挑战:
enum Apple: String {
case braeburn
case macintosh
case honeycrisp
}
protocol AppleProtocol {
var brand: Apple { get set }
}
protocol AppleGetter {
func getApple<T>(for key: Apple) -> T?
}
protocol PropertyReflectable { }
extension PropertyReflectable {
subscript(key: String) -> Any? {
let m = Mirror(reflecting: self)
return m.children.first { $0.label == key }?.value
}
}
struct GenericApple<T: Equatable>: AppleProtocol, Hashable {
static func == (lhs: GenericApple<T>, rhs: GenericApple<T>) -> Bool {
return lhs.brand == rhs.brand
}
var hashValue: Int { return brand.hashValue }
var brand: Apple
var generic: T
init(brand: Apple, generic: T) {
self.brand = brand
self.generic = generic
}
}
struct Apples {
typealias Braeburn = GenericApple<Int>
var braeburn = Braeburn(brand: .braeburn, generic: 10)
typealias Honeycrisp = GenericApple<String>
var honeycrisp = Honeycrisp(brand: .honeycrisp, generic: "A generic")
}
extension Apples: PropertyReflectable {
func getApple<T>(for key: Apple, type: T.Type) -> T? {
return self[key.rawValue] as? T
}
}
这太棒了!
var applesSet = Apples()
var braeburn = applesSet.getApple(for: Apple.braeburn, type: Apples.Braeburn.self)
braeburn?.generic = 14
print(braeburn?.generic)
但如果我想做:
struct AppleListElement {
let brand: Apple
let type: String
}
var apples = [AppleListElement]()
apples.append(AppleListElement(brand: .braeburn, type: "\(Apples.Braeburn.self)"))
apples.append(AppleListElement(brand: .honeycrisp, type: "\(Apples.Honeycrisp.self)"))
apples.forEach {
applesSet.getApple(for: $0.brand, type: NSClassFromString($0.type))
}