我有两个类(class): CatHelper和DogHelper,都是从DataHelper继承过来的,都只包含类函数。
我想要一个 [DataHelper : [String]] 类型的字典
为此,我使 DataHelper 符合 Hashable + Equatable
但是我很难实例化这样一个字典。这是我到目前为止尝试过的
let apiURLS:[DataHelper : [String]] = [CatHelper : ["abc","def"], DogHelper:["ddd"], DogHelper: ["fff"]]
但是编译器说“无法将 CatHelper.Type 类型的值转换为预期的 DataHelper 类型的字典键”
编辑:
然后,我想遍历这个字典来做,在这个例子中
CatHelper.feed("abc")
CatHelper.feed("def")
DogHelper.feed("ddd")
DogHelper.feed("fff")
在这种情况下,拥有 CatHelper 或 DogHelper 的实例没有用,因为我只使用类函数。
最佳答案
因为你的字典是这样声明的
let apiURLS:[DataHelper : [String]]
这意味着键必须是 DataHelper
类型的实例。
要获取 DataHelper 类型的实例,您可以编写
DataHelper()
DataHelper 子类的实例也是有效的:
CatHelper()
DogHelper()
所以
let apiURLS:[DataHelper:[String]] = [
CatHelper(): ["abc","def"],
DogHelper(): ["ddd"],
DogHelper(): ["fff"]
]
更新
从您的评论(和更新的问题)中我看到您希望字典的键确实是类的类型,而不是实例。
我认为这是不可能的,因为
let apiURLS:[DataHelper.Type : [String]] = [
CatHelper.self: ["abc","def"],
DogHelper.self: ["ddd"],
DogHelper.self: ["fff"]
]
error: type 'DataHelper.Type' does not conform to protocol 'Hashable'
let apiURLS:[DataHelper.Type : [String]] = [
^
所以我们不能使用类类型作为字典的键。
好吧,让我们探索另一个解决方案
这个 Wrapper 可以包含 DataHelper
的类型或者 DataHelper
的子类类型。
class Wrapper:Hashable, Equatable {
let value: DataHelper.Type
init(_ value:DataHelper.Type) {
self.value = value
}
var hashValue: Int { get { return "\(value)".hashValue } }
}
func ==(left:Wrapper, right:Wrapper) -> Bool {
return left.value == right.value
}
像这样
Wrapper(CatHelper.self)
由于包装器是 Hashable 并且 Equatable 可以用作 Dictionary
中的键。
现在
let apiURLS:[Wrapper : [String]] = [
Wrapper(CatHelper.self): ["abc","def"],
Wrapper(DogHelper.self): ["ddd"],
Wrapper(DogHelper.self): ["fff"]
]
迭代
apiURLS
.map { ($0.0.value, $0.1) }
.forEach { (classType, strings) -> () in
classType.feed("Wow")
}
关于Swift 字典键类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34500065/