1

我有两个类: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 的实例没有用,因为我只使用类函数。

4

2 回答 2

1

由于您的字典是这样声明的

let apiURLS:[DataHelper : [String]]

这意味着键必须是 type 的实例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")
}
于 2015-12-28T20:18:47.403 回答
0

好的,经过一番摆弄后,它开始工作了:

let apiURLS:[(String -> (),[String])] = [(CatHelper.feed, ["abc","def"]), (DogHelper.feed, ["ddd"]), (DogHelper.feed, ["fff"])]

apiURLS.forEach { (f, x) in
    x.forEach {
        f($0)
    }
}

变化基本上是你不再有一个字典(由于重复的键,它一开始就不起作用)而是一个数组。在数组中,您有一个要调用的函数和输入的元组。

使用以下代码作为构建基线:

class DataHelper {
    class func feed(a:String) {
        print("data ate \(a)")
    }
}

class CatHelper : DataHelper {
    override class func feed(a:String) {
        print("cat ate \(a)")
    }
}

class DogHelper : DataHelper {
    override class func feed(a:String) {
        print("dog ate \(a)")
    }
}

它输出

猫吃了 abc
猫吃了 def
狗吃了 ddd
狗吃了 fff

于 2015-12-28T20:37:50.123 回答