我想创建一个Dictionary不限制键类型(如NSDictionary)
所以我试过了
var dict = Dictionary<Any, Int>()
Run Code Online (Sandbox Code Playgroud)
和
var dict = Dictionary<AnyObject, Int>()
Run Code Online (Sandbox Code Playgroud)
造成
error: type 'Any' does not conform to protocol 'Hashable'
var dict = Dictionary<Any, Int>()
^
<REPL>:5:12: error: cannot convert the expression's type '<<error type>>' to type '$T1'
var dict = Dictionary<Any, Int>()
^~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
好的,我会用的 Hashable
var dict = Dictionary<Hashable, Int>()
Run Code Online (Sandbox Code Playgroud)
但
error: type 'Hashable' does not conform to protocol 'Equatable'
var dict = Dictionary<Hashable, Int>()
^
Swift.Equatable:2:8: note: '==' requirement refers to 'Self' type
func ==(lhs: Self, rhs: Self) -> Bool
^
Swift.Hashable:1:10: note: type 'Hashable' does not conform to inherited protocol 'Equatable.Protocol'
protocol Hashable : Equatable
^
<REPL>:5:12: error: cannot convert the expression's type '<<error type>>' to type '$T1'
var dict = Dictionary<Hashable, Int>()
^~~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
所以Hashable继承自Equatable但不符合Equatable??? 我不明白......
无论如何,继续努力
typealias KeyType = protocol<Hashable, Equatable> // KeyType is both Hashable and Equatable
var dict = Dictionary<KeyType, Int>() // now you happy?
Run Code Online (Sandbox Code Playgroud)
没有运气
error: type 'KeyType' does not conform to protocol 'Equatable'
var dict = Dictionary<KeyType, Int>()
^
Swift.Equatable:2:8: note: '==' requirement refers to 'Self' type
func ==(lhs: Self, rhs: Self) -> Bool
^
Swift.Hashable:1:10: note: type 'KeyType' does not conform to inherited protocol 'Equatable.Protocol'
protocol Hashable : Equatable
^
<REPL>:6:12: error: cannot convert the expression's type '<<error type>>' to type '$T1'
var dict = Dictionary<KeyType, Int>()
^~~~~~~~~~~~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
我现在迷失了,我怎么能让编译器满意我的代码呢?
我想用字典之类的
var dict = Dictionary<Any, Int>()
dict[1] = 2
dict["key"] = 3
dict[SomeEnum.SomeValue] = 4
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用Dictionary<NSObject, Int>,但它并不是我想要的.
Yar*_*neo 58
您现在可以使用AnyHashable哪个是类型擦除的hashable值,完全针对这样的场景创建:
var dict = Dictionary<AnyHashable, Int>()
jul*_*les 16
我相信,从Swift 1.2开始,您可以使用ObjectIdentifier结构.它实现Hashable(因此Equatable)以及Comparable.您可以使用它来包装任何类实例.我猜测实现使用包装对象的hashValue底层地址,以及==运算符.
Chr*_*ver 11
我冒昧地在Apple Dev论坛的另一篇文章中交叉发布/链接到这个问题,这个问题在这里得到解答.
以上链接的答案适用于6.1及更高版本:
struct AnyKey: Hashable {
private let underlying: Any
private let hashValueFunc: () -> Int
private let equalityFunc: (Any) -> Bool
init<T: Hashable>(_ key: T) {
underlying = key
// Capture the key's hashability and equatability using closures.
// The Key shares the hash of the underlying value.
hashValueFunc = { key.hashValue }
// The Key is equal to a Key of the same underlying type,
// whose underlying value is "==" to ours.
equalityFunc = {
if let other = $0 as? T {
return key == other
}
return false
}
}
var hashValue: Int { return hashValueFunc() }
}
func ==(x: AnyKey, y: AnyKey) -> Bool {
return x.equalityFunc(y.underlying)
}
Run Code Online (Sandbox Code Playgroud)
字典struct Dictionary<Key : Hashable, Value>...
意味着Value可以是你想要的任何东西,Key可以是你想要的任何类型,但Key必须符合Hashable协议.
您无法创建Dictionary<Any, Int>()或Dictionary<AnyObject, Int>(),因为Any并AnyObject不能保证这样的密钥符合Hashable
你不能创建Dictionary<Hashable, Int>(),因为Hashable它不是一种类型,它只是描述所需类型的协议.
Hashable继承自Equatable,但它不符合Equatable ??? 我不明白......
但你的术语是错的.原始错误是
type 'Hashable' does not conform to inherited protocol 'Equatable.Protocol'
这意味着Xcode假定'Hashable'为某种类型,但没有这种类型.并且Xcode将它视为某种类型的空类型,它显然根本不符合任何协议(在这种情况下它不符合继承的协议Equatable)
类似的事情发生在KeyType.
类型别名声明将现有类型的命名别名引入程序.
你看existing type.protocol<Hashable, Equatable>它不是一种类型的协议,所以Xcode再次告诉你type 'KeyType' does not conform to protocol 'Equatable'
你可以使用Dictionary<NSObject, Int>just,因为NSObject符合Hashable协议.
Swift是强类型语言,你不能做一些像creating Dictionary that can hold anything in Key.实际上字典已经支持任何可以在Key中保存的东西,这符合Hashable.但是因为你应该指定特定的类,你不能为本机的Swift类做这个,因为Swift中没有像Objective-C那样的大师类,它符合空气可以符合(借助扩展)到Hashable
当然你可以使用像chrisco建议的一些包装器.但我真的无法想象你为什么需要它.很高兴你在Swift中有强大的输入,所以你不必像在Objective-C中那样担心类型转换
Hashable只是一个协议,因此您不能直接将其指定为Key值的类型。你真正需要的是一种表达“任何类型 T 的方式,使得 T 实现Hashable。这是通过 Swift 中的类型约束来处理的:
func makeDict<T: Hashable>(arr: T[]) {
let x = Dictionary<T, Int>()
}
Run Code Online (Sandbox Code Playgroud)
这段代码可以编译。
AFAIK,您只能对泛型函数和类使用类型约束。
| 归档时间: |
|
| 查看次数: |
26282 次 |
| 最近记录: |