Swift 结构类型集 [英] Swift Set of Structure Types
问题描述
假设我有一个 struct
,它可以是任何东西:
Say I have a struct
, which could be anything:
struct Cube {
var x: Int
var y: Int
var z: Int
var width: Int
// ...
}
然后我如何创建这些点的 Set
,这样就不会有两个具有相同属性的对象?
How do I then create a Set
of these points, such that there will be no two objects with the same properties?
let points: Set<Cube> = Set()
// Type ‘Cube’ does not conform to protocol ‘Hashable’
但是如何实现可散列并不是很明显.从我读到的内容来看,我需要创建一个散列函数,但鉴于我在结构中拥有的属性数量,这看起来并不容易.
But it’s not immediately obvious how to implement hashable. From what I read, I need to make a hash function, but that doesn’t look easily possible with the amount of properties I have in the struct.
推荐答案
首先,Hashable
扩展了 Equatable
,所以你必须实现==
运算符,它使用所有属性比较两个值唯一标识一个多维数据集:
First of all, Hashable
extends Equatable
, so you must implement
a ==
operator which compares two values, using all properties
which uniquely identify a cube:
func ==(lhs: Cube, rhs: Cube) -> Bool {
return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.width == rhs.width
}
Hashable
协议仅要求
x == y
意味着 x.hashValue == y.hashValue
所以
var hashValue: Int {
return 0
}
将是一个有效(且有效)的实现.然而,这会将所有对象放在集合(或字典)的同一个哈希桶中,这是无效的.一个更好的实现是例如
would be a valid (and working) implementation. However, this would put all objects in the same hash bucket of a set (or dictionary), which is not effective. A better implementation is for example
struct Cube: Hashable {
var x: Int
var y: Int
var z: Int
var width: Int
var hashValue: Int {
return x.hashValue ^ y.hashValue ^ z.hashValue ^ width.hashValue
}
}
这里选择了XOR"运算符^
,因为它不会溢出.您还可以使用溢出运算符"&+
.
Here the "XOR" operator ^
is chosen because it cannot overflow.
You could also use the "overflow operator" &+
.
更复杂的哈希函数将能够区分不同的值更好,使集合操作变得更快.另一方面,哈希函数本身的计算会更慢.因此我会寻找一个更好的"哈希函数仅当集合操作成为您程序的性能瓶颈时.
More sophisticated hash functions would be able to distinguish different values better, so that the set operations become faster. On the other hand, the computation of the hash function itself would be slower. Therefore I would look for a "better" hash function only if the set operations turn out to be a performance bottleneck in your program.
更新:从 Swift 4.1 (Xcode 9.4) 开始,编译器可以综合==
和 hashValue
方法,如果结构体的所有成员都是Equatable/Hashable
.因此足以声明一致性:
Update: As of Swift 4.1 (Xcode 9.4) the compiler can synthesize
the ==
and hashValue
methods if all members of the struct are
Equatable/Hashable
. Therefore is suffices to declare the conformance:
struct Cube: Hashable {
var x: Int
var y: Int
var z: Int
var width: Int
}
这篇关于Swift 结构类型集的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!