Swift:具有相同属性的不同对象:哈希值

标签 swift hash

目前我有一个泛型类,我想让这个类的对象可以通过

搜索
contains()

这些对象数组的方法,通过使类符合 Hashable 协议(protocol)并为每个对象提供哈希值。现在我的问题是我有具有完全相同属性的对象,而且数组似乎无法真正区分它们(我目前的方法是使用属性的哈希值之一作为类的哈希值,而

== <T> (lhs: ClassA<T>, rhs: ClassA<T>) -> Bool

函数是通过比较哈希值来完成的)。我曾尝试使用像“id”这样的静态属性,但对于泛型类型,不支持静态属性。

我应该如何定义散列值,以便仍然可以区分具有相同属性的不同对象?

编辑:我让它直接符合 Hashable,因为它也在程序的其他部分用作 dict 中的键,因为 Hashable 已经符合 Equatable。

最佳答案

My current approach is to use one of the properties' hash value as the hash value for the class, and the

== <T> (lhs: ClassA<T>, rhs: ClassA<T>) -> Bool

function is done by comparing the hash value

== 不是这样的和 hashValue关系有效——不要这样做。如果发生哈希冲突怎么办?具有不同属性的两个不同实例可以比较相等。

您应该改为执行 == 实际比较两个实例的属性。 ==应该返回 true如果两个给定的实例具有相同的属性。 hashValue如果两个实例的 s 与 == 比较相等,则它们应该是等价的.

现在,除非T,否则您很可能无法进行此比较。是Equatable .一种解决方案是不符合 ClassAEquatable , 而只是重载 ==什么时候TEquatable ,例如:

func == <T : Equatable>(lhs: ClassA<T>, rhs: ClassA<T>) -> Bool {
    // stub: do comparison logic
}

您现在可以使用 Sequence contains(where:) 方法结合 ==重载以检查给定实例是否在数组中:

var array = [ClassA("foo")] // assuming ClassA has an init(_: T) and a suitable ==
                            // implementation to compare that value

let someInstanceToFind = ClassA("foo")
print(array.contains { $0 == someInstanceToFind }) // true

如果你想要ClassA有一个hashValue , 然后简单地写一个 extension定义了 hashValue什么时候THashable :

extension ClassA where T : Hashable {
    var hashValue: Int {
        return 0 // to do: implement hashValue logic
    }
}

不幸的是,这确实意味着 ClassA不会明确符合 Hashable什么时候T会——但它会有一个 hashValue==执行。 SE-0143: Conditional conformances如果给定where,将通过允许明确遵守协议(protocol)来改变这一点子句是否满足,但尚未实现。

如果您需要明确符合 Hashable (例如在 SetDictionary 键中使用您的类的实例)——那么一个解决方案是创建一个包装类型:

struct HashableClassA<T : Hashable> : Hashable {

    var base: ClassA<T>

    init(_ base: ClassA<T>) {
        self.base = base
    }

    static func ==(lhs: HashableClassA, rhs: HashableClassA) -> Bool {
        return lhs.base == rhs.base
    }

    var hashValue: Int {
        return base.hashValue
    }
}

现在你只需要包装 ClassA<T> HashableClassA 中的实例添加到 Set 之前的实例或 Dictionary .

关于Swift:具有相同属性的不同对象:哈希值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41727954/

相关文章:

ios - 在包含多个图像的UIDocument中处理图像加载/存储

ios - 按下按钮后,如何使 UIPickerView 从应用程序底部升起?

swift - 将 KVO 添加到设置包

python - 在 Python 中使用 hashlib 检测可用的非标准哈希算法

hash - 多对一映射哈希函数

swift - AVPlayer 需要很长时间才能开始播放 url 中的歌曲

Swift 概述 SKLabelNodes

java - 编码结果相同,但散列结果不同

hash - 为什么 md5 和 sha-* 在其哈希结果中仅使用字母数字字符?

encryption - 将低级 OpenSSL API 迁移到高级 OpenSSL API 所需的建议