前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Swift之Hashable协议

Swift之Hashable协议

作者头像
SheltonWan
修改2019-07-01 15:01:31
3.9K0
修改2019-07-01 15:01:31
举报

Overview

符合Hashable协议的任何类型,既可以在集合(Set)中使用,也可以作为字典键使用。默认情况下,标准库中的许多类型都符合Hashable:字符串,整数,浮点和布尔值,还有事件集合(even sets)。其他类型(例如,选项(optionals),数组(Array)和范围(Range))在其类型参数实现符合hashable时就会自动变为hashable。

您自己定义的类型也可以hashable。当您定义没有关联值的枚举时,它会自动获得Hashable符合性,并且您可以通过实现hash(into :)方法将Hashable符合性添加到其他自定义类型。对于其存储属性都是符合Hashable的结构,以及具有all-Hashable关联值的枚举类型,编译器能够自动提供hash(into :)的实现。

散列值意味着将其基本组件(essential component)提供给哈希函数,由哈希类型表示。基本组件(essential component)是那些有助于Equatable类型实现的组件。两个相等的实例必须以相同的顺序将相同的值提供给Hasher的hash(into :)。

Conforming to Hashable Protocol

要在集合中使用您自己的自定义类型或作为字典的键类型,请在类型中遵循Hashable协议。 Hashable协议继承自Equatable协议,因此您还必须满足该协议的要求。

当您在类型的原始声明中遵循Hashable协议并且您的类型符合以下条件时,编译器会自动合成您的自定义类型的Hashable和要求:

  • 对于结构,其所有存储的属性必须遵循Hashable。
  • 对于枚举,其所有关联值必须遵循Hashable。 (即使没有声明,没有关联值的枚举也具有Hashable一致性。)

要自定义你的类型以遵循Hashable协议,或者要在不符合上面列出的条件的类型中遵循Hashable,或者要扩展现有类型以遵循Hashable,请在自定义类型中实现hash(into :)方法。

在你的hash(into :)实现中,在提供的Hasher实例上以你的类型的基本组件调用combine(_ :)。为确保您的类型符合Hashable和Equatable协议的语义要求,最好还要自定义类型的Equatable一致性(conformance)以匹配。

例如,考虑一个GridPoint类型,它描述按钮网格中的位置。这是GridPoint类型的初始声明:

/// x-y坐标系中的一个点。

struct GridPoint {

var x:Int

var y:Int

}

您想要创建一组用户点击过的网格点。由于GridPoint类型尚不遵循hashable,因此无法在集合中使用。要添加Hashable一致性,请提供==运算符函数并实现hash(into :)方法。

extension GridPoint:Hashable {

static func ==(lhs:GridPoint,rhs:GridPoint) - > Bool {

r eturn lhs.x == rhs.x && lhs.y == rhs.y

}

func hash(into hasher:inout Hasher){

hasher.combine(x)

hasher.combine(y)

}

}

此示例中的hash(into :)方法将网格点的x和y属性提供给(feed)提供的hasher。这些属性与用于在==运算符函数中测试相等性的属性相同。

现在GridPoint符合Hashable协议,您可以创建一组先前点击的网格点。

var tappedPoints:Set = [GridPoint(x:2,y:3),GridPoint(x:4,y:1)]

let nextTap = GridPoint(x:0,y:1)

If tappedPoints.contains(nextTap){

print(“已经点击了(\(nextTap.x),\(nextTap.y))。”)

} else {

tappedPoints.insert(nextTap)

print(“在(\(nextTap.x),\(nextTap.y))检测到新点击。”)

}

//打印“在(0,1)处检测到新点击。”)

本文系外文翻译,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系外文翻译前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档