Swift 结构类型集 [英] Swift Set of Structure Types

查看:43
本文介绍了Swift 结构类型集的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆