使简单元组符合Hashable,因此可以是Dictionary Key

Con*_*sed 3 dictionary protocols hashable swift

我想用一个非常简单的元组作为关键:

(Int, Int)
Run Code Online (Sandbox Code Playgroud)

字典键需要是Hashable.我学到了

但是找不到我如何使这个简单的元组Hashable,并且最好在协议一致性方面做斗争.

更深刻的是,CGPoint可以解决我的问题.它可以是这种格式,但不可清除.

是否可以扩展CGPoint以便它可以清洗?如果是这样,怎么样?

编辑:CGPoint选择的Int变体的图像.

在此输入图像描述

OOP*_*Per 6

Hashable对于类,结构或枚举来说,使符合并不困难.您只需要明确声明符合性Hashable并定义属性hashValue: Int.实际上,hashValue需要实现一个简单的公理:如果a == b则a.hashValue == b.hashValue.

(为了符合Hashable,你还需要制作类型Equatable.如果是CGPoint,它已经是Equatable.)

CGPoint符合以下要求的示例Hashable:

extension CGPoint: Hashable {
    public var hashValue: Int {
        //This expression can be any of the arbitrary expression which fulfills the axiom above.
        return x.hashValue ^ y.hashValue
    }
}

var pointDict: [CGPoint: String] = [
    CGPoint(x: 1.0, y: 2.0): "PointA",
    CGPoint(x: 3.0, y: 4.0): "PointB",
    CGPoint(x: 5.0, y: 6.0): "PointC",
]
print(pointDict[CGPoint(x: 1.0, y: 2.0)]) //->Optional("PointA")
Run Code Online (Sandbox Code Playgroud)

由于CGPoint包含CGFloat值,因此,CGPoint作为字典的键可能会导致基于二进制浮点系统的计算错误的意外行为.你需要格外小心使用它.


加成

如果你想避免一些计算错误问题并且可以接受结构只能包含Ints,你可以定义自己的结构并使其符合Hashable:

struct MyPoint {
    var x: Int
    var y: Int
}
extension MyPoint: Hashable {
    public var hashValue: Int {
        return x.hashValue ^ y.hashValue
    }

    public static func == (lhs: MyPoint, rhs: MyPoint) -> Bool {
        return lhs.x == rhs.x && lhs.y == rhs.y
    }
}
var myPointDict: [MyPoint: String] = [
    MyPoint(x: 1, y: 2): "MyPointA",
    MyPoint(x: 3, y: 4): "MyPointB",
    MyPoint(x: 5, y: 6): "MyPointC",
]
print(myPointDict[MyPoint(x: 1, y: 2)]) //->Optional("MyPointA")
Run Code Online (Sandbox Code Playgroud)

比上面的代码困难得多,您需要的另一件事就是==为结构定义运算符.请试一试.