1

CatHelper と DogHelper の 2 つのクラスがあります。どちらも 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]] = [
        ^

したがって、クラス型を辞書のキーとして使用することはできません。

では、別の解決策を探ってみましょう

このラッパーには、 のタイプ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 に答える