Изготовление соответствует 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")
Как CGPoint
содержит CGFloat
значений, поэтому CGPoint
в качестве ключа словаря может привести к неожиданному поведению, основанному на ошибке вычисления двоичной системы с плавающей запятой. Вы должны использовать его с особой осторожностью.
Сложение
Если вы хотите, чтобы избежать некоторых проблем ошибки вычисления и можете признать, что структура может содержать только Int
с, вы можете определить свои собственную структуру и сделать его соответствовать 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")
Не намного сложнее, чем приведенный выше код, еще одна вещь, в которой вы нуждаетесь, - это просто определение оператора для структуры. ==
. Пожалуйста, попробуйте.
Связанный: [В Swift я могу использовать кортеж в качестве ключа в словаре?] (Http://stackoverflow.com/q/24131323/2976878) – Hamish