我知道Swift没有通配符类型来专门化泛型类型。我有一个问题,我知道如何使用 Java 等语言来解决这些问题。
在下面的示例中,我尝试定义一个struct Property
,它封装了对类型T
的属性的访问,以执行两个操作,获取该属性的值的哈希值T的一个实例,并在T
的两个实例上比较属性的值。为了实现这一点,struct包含一个属性getter
,它包含一个返回实例上特定属性值的函数。因此,结构不仅需要在T
中是通用的,还需要属性的类型E
。
在struct Test
中,我想定义一个静态属性properties
,其中包含Property
个实例的数组,每个属性为Test
一个。我无法看到这样做的方法,因为我不知道properties
使用什么类型或如何“隐藏”类型参数E
,因此不需要在声明中指定它properties
。
// Struct which represents a property of type T with a value of type E.
// Aside from initialization only T is visible from outside.
public struct Property<T, E: Hashable> {
let getter: (T) -> E
func getMemberHashValue(instance: T) -> Int {
return getter(instance).hashValue
}
func equalsMembers(instance1: T, instance2: T) -> Bool {
return getter(instance1) == getter(instance2)
}
}
struct Test {
// Some properties with different types
let a: Int
let b: Double
// Array of Property instances for all properties of Test.
// Not valid syntax.
let properties: [Property<Test, ?>] = [
Property(getter: { (instance: Test) in instance.a }),
Property(getter: { (instance: Test) in instance.b })]
}
我知道在这种情况下,我可以在properties
的声明中替换AnyHashable作为第二个类型参数,因为它没有关联的类型,但我想找到一个我可以应用的通用解决方案不涉及Hashable
的案件。
是否有办法更改此示例以允许为不同类型的属性定义包含多个properties
实例的属性Property
?
答案 0 :(得分:0)
如果绝对需要,如果是,请使用NSArray
/ NSMutableArray
如果您想动态访问class
/ struct
/ enum
的属性,可以使用KeyPath
进行操作。
struct Test : Hashable {
// Some properties with different types
let a: Int
let b: Double
let c: String
//This function will return any property of Test instance
func property<T>(forKeyPath keyPath: KeyPath<Test, T>) -> T {
return self[keyPath: keyPath]
}
//MARK: Hashable
var hashValue: Int {
return a.hashValue ^ b.hashValue ^ c.hashValue
}
//MARK: Equatable
static func ==(lhs: Test, rhs: Test) -> Bool {
return lhs.a == rhs.a &&
lhs.b == rhs.b &&
lhs.c == rhs.c
}
}
let test1 = Test(a: 10, b: 22.22, c: "aaaa")
let cValue = test1.property(forKeyPath: \.c) //aaaa
let cHashValue = test1.property(forKeyPath: \.c.hashValue) //Hash value of aaaa
let someInt = 10 //This is also Hashable
var mixedArray = [AnyHashable]()
mixedArray.append(test1)
mixedArray.append(someInt)
如果符合您的要求,请阅读KeyPath
,PartialKeyPath
。
Swift 4