我正在尝试将枚举值映射到结构上的属性,这样可以通过枚举访问这些属性,并且可以以通用的方式迭代和处理这些属性。下面是一个精心设计的例子,它演示了我遇到的编译器错误:
import UIKit
protocol AProtocol: Equatable {
var someInstanceProperty: String { get }
}
extension Bool: AProtocol {
var someInstanceProperty: String { "Bool" }
}
extension Int: AProtocol {
var someInstanceProperty: String { "Int" }
}
extension String: AProtocol {
var someInstanceProperty: String { "String" }
}
struct Values {
var someBool = false
var someInt = 0
var someString = "hello"
enum Properties {
case someB, someI, someS
}
let map1: [Properties: PartialKeyPath<Values>] = [
.someB: \Values.someBool,
.someI: \Values.someInt,
.someS: \Values.someString,
]
let map2: [Properties: KeyPath<Values, AProtocol>] = [
.someB: \Values.someBool, // Cannot convert value of type 'KeyPath<Values, Bool>' to expected dictionary value type 'KeyPath<Values, AProtocol>'
.someI: \Values.someInt, // Cannot convert value of type 'KeyPath<Values, Int>' to expected dictionary value type 'KeyPath<Values, AProtocol>'
.someS: \Values.someString, // Cannot convert value of type 'KeyPath<Values, String>' to expected dictionary value type 'KeyPath<Values, AProtocol>'
]
func performSomeAction<T: AProtocol>(key: Properties, keyPath: KeyPath<Values, T>) {
print("key \(key), value \(self[keyPath: keyPath].someInstanceProperty)")
}
func getAll1() {
for (key, keyPath) in map1 {
performSomeAction(key: key, keyPath: keyPath) // Cannot convert value of type 'PartialKeyPath<Values>' to expected argument type 'KeyPath<Values, T>'
}
}
func getAll2() {
for (key, keyPath) in map1 {
print("key \(key), value \(self[keyPath: keyPath].someInstanceProperty)") // Value of type 'Any?' has no member 'someInstanceProperty'
}
}
func getAll3() {
for (key, keyPath) in map1 {
print("key \(key), value \((self[keyPath: keyPath] as! AProtocol).someInstanceProperty)") // Protocol 'AProtocol' can only be used as a generic constraint because it has Self or associated type requirements
}
}
}
在里面
map1
,值类型为
PartialKeyPath
.我不能用
KeyPath
因为值类型不同(即使它们都符合
AProtocol
),所以我得到了一个编译器错误(请参阅
map2
)。的问题
map1
值会丢失其类型信息。三人
getAll
函数展示了我试图克服的各种方法,但都没有成功。我最接近的是
getAll3
,如果我删除
Equatable
一致性来自
A协议
。不幸的是,我需要这些值在我的真实代码中是相等的。我正在将以前存储的值与当前属性值进行比较。这可能吗?