在Swift中,我可以使用元组作为字典中的键?
我想知道如果我可以以某种方式使用x,y对作为我的字典的关键
let activeSquares = Dictionary <(x: Int, y: Int), SKShapeNode>()
但是我得到的错误:
Cannot convert the expression's type '<<error type>>' to type '$T1'
和错误:
Type '(x: Int, y: Int)?' does not conform to protocol 'Hashable'
那么,我们怎样才能让它符合?
Dictionary
的定义是struct Dictionary<KeyType : Hashable, ValueType> : ...
,即密钥的types必须符合协议Hashable
。 但是语言指南告诉我们, 协议可以被类,结构和枚举所采用 ,即不能被元组所采用。 因此,元组不能用作Dictionary
键。
一个解决方法是定义一个包含两个Ints(或任何你想放在你的元组中)的可哈希结构types。
正如上面的答案中所提到的,这是不可能的。 但是你可以使用Hashable协议将元组打包到generics结构中作为一个解决方法:
struct Two<T:Hashable,U:Hashable> : Hashable { let values : (T, U) var hashValue : Int { get { let (a,b) = values return a.hashValue &* 31 &+ b.hashValue } } } // comparison function for conforming to Equatable protocol func ==<T:Hashable,U:Hashable>(lhs: Two<T,U>, rhs: Two<T,U>) -> Bool { return lhs.values == rhs.values } // usage: let pair = Two(values:("C","D")) var pairMap = Dictionary<Two<String,String>,String>() pairMap[pair] = "A"
我在一个应用中创build了这个代码:
struct Point2D: Hashable{ var x : CGFloat = 0.0 var y : CGFloat = 0.0 var hashValue: Int { return "(\(x),\(y))".hashValue } static func == (lhs: Point2D, rhs: Point2D) -> Bool { return lhs.x == rhs.x && lhs.y == rhs.y } } struct Point3D: Hashable{ var x : CGFloat = 0.0 var y : CGFloat = 0.0 var z : CGFloat = 0.0 var hashValue: Int { return "(\(x),\(y),\(z))".hashValue } static func == (lhs: Point3D, rhs: Point3D) -> Bool { return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z } } var map : [Point2D : Point3D] = [:] map.updateValue(Point3D(x: 10.0, y: 20.0,z:0), forKey: Point2D(x: 10.0, y: 20.0)) let p = map[Point2D(x: 10.0, y: 20.0)]!
如果你不介意一点低效,你可以很容易地将你的元组转换成一个string,然后用它作为字典键。
var dict = Dictionary<String, SKShapeNode>() let tup = (3,4) let key:String = "\(tup)" dict[key] = ...