2017-05-23 17 views
2

2つのDictionaryオブジェクトをマージしようとしています。彼らは両方のkeyためvalueを持っているとき、私は例外のカップルと、最初のを上書きするために第2のDictionayの値をしたいと思います:"_"型を参照するエラー: "'[値]'型の値を '_?'に割り当てることができません"

  • 両方の値がDictionaryオブジェクトであるとき、私はあることを彼らが欲しいです再帰的に同じメソッドを使用してマージされます。
  • 両方の値がArrayのオブジェクトの場合、それらを連結したいと思います。

次のように私のコードは次のとおりです。

extension Dictionary where Key:Hashable, Value:AnyObject { 
    func merge(with second: [Key : Value]) -> [Key : Value] { 
     var resultDictionary = self 

     for (key, value) in second { 
      switch value { 
      case let newDict as [Key : Value]: 
       if let oldDict = resultDictionary[key] as? [Key : Value] { 
        resultDictionary[key] = oldDict.merge(with: newDict) // 1 
       } else { 
        resultDictionary[key] = newDict // 2 
       } 

      case let newArray as [Value]: 
       if let oldArray = resultDictionary[key] as? [Value] { 
        resultDictionary[key] = oldArray + newArray // 3 
       } else { 
        resultDictionary[key] = newArray // 4 
       } 

      default: 
       resultDictionary[key] = value 
      } 
     } 

     return resultDictionary 
    } 
} 

私はコメント行に取得しています:期待される引数の型に:「[値キー]」

  1. は、型の値を変換できません。 '[_:_]'
  2. タイプ '[Key:Value]'の値を '_'に割り当てることはできません。
  3. タイプ '[値]'の値を '_'型に割り当てることができません。
  4. タイプ '[値]'の値を '_'型に割り当てることができません。

これらのすべてのエラーは、非常に密接に関連していない場合、同じだと思います。ここではアンダースコアがタイプとして使われているようですが、私はこの意味での意味ではありません。私は、アンダースコアは未使用の変数を示すためにのみ使用されたと考えました。

+2

ここでアンダースコアは、型が不可能であることが多いため、型を一意に決定できないことを意味します。 Sulthanが指摘しているように、あなたのケースでは、最初の 'case 'が機能するために' Value'は '[Key:Value]'と等価でなければなりません。これは不可能です(型を無限に再帰的にします)。だから、エラーメッセージに '_'をつけることになります。 –

+1

'Key:Hashable'という制約は冗長です。これは' struct Dictionary'で既に必要です。 –

答えて

2

次の2つに式を分割することによって、あなたのエラーを実現することができます。今すぐあなたがValueを入力見込んで何かに[Key: Value]辞書を割り当てる

let newValue: [Key: Value] = oldDict.merge(with: newDict) 
resultDictionary[key] = newValue // 1 

注意を。あなたはタイプの観点からキャスト

resultDictionary[key] = newValue as? Value // 1 

が必要

が、これはすべての非常に奇妙です。いくつかの提供されたタイプに辞書をキャストしようとしてはいけません。

AnyObjectの値を持つ辞書に関数を追加しないのはなぜですか?

extension Dictionary where Key:Hashable, Value == AnyObject 

、その後

resultDictionary[key] = newValue as AnyObject 

キャストは、今素敵で安全なコンパイル時のキャストです。

+0

あなたのソリューションとアップデートをありがとう。私は以前はコンパイル時のキャストは考えていませんでした。ランタイム・タイプは、私が実装していたときには安全ではないようでしたが、私の選択肢が何であるかはわかりませんでした。再度、感謝します。 –

+1

@JoshParadroidこれで、 'AnyObject'にキャストすることで、実際に辞書をObj-Cの' NSDictionary'にキャストする必要があります。 Swiftでは、辞書は値型であり、 'AnyObject'ではありません。この場合、普通の 'Any'を使う方が良い解決法かもしれません。 – Sulthan

+0

私は実際にそこに非オブジェクト値を格納する必要があったので、とにかくそれを切り替えました。スウィフトの内部の仕組みがいかに感謝しているのかを知ることは、常に素晴らしいことです。 –

関連する問題