我知道 Swift 没有通配符类型来专门处理泛型类型。我有一个问题,我会知道如何在像Java这样的语言中使用它们来解决。
在下面的示例中,我尝试定义一个结构Property
,该结构封装对类型属性的访问,T
执行两个操作,在 T 实例上获取该属性值的哈希值,并在两个T
实例上比较该属性的值。为了允许这一点,结构包含一个属性getter
保存一个函数,该函数返回实例上特定属性的值。因此,结构不仅需要在T
中是泛型的,而且在属性的类型E
中也需要泛型。
在结构式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 })]
}
我知道在这种情况下,我可以将 AnyHashable 替换为properties
声明中的第二个类型参数,因为它没有关联的类型,但我想找到一个通用解决方案,我可以在不涉及Hashable
的情况下应用。
有没有办法更改此示例以允许定义此类属性properties
,其中包含不同类型的属性的多个Property
实例?
概述:
我- 不确定我是否正确理解了你的问题。
- 可能值得说明为什么你想要一个异构数组,在这个过程中会失去所有类型的安全性。
- 可能正在重新审视设计
选项 1:
如果绝对需要,如果是这样,只需使用NSArray
/NSMutableArray
选项 2:
如果要动态访问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
的信息。
版本:
斯威夫特 4