2016-09-27 15 views
1

、私は私が列挙メンバーを使用して、辞書の値を格納および取得することができちょっといいセットアップを持っていた:スウィフト3ジェネリック拡張引数スウィフト2.xでは

public enum UserDefaultsKey : String { 
    case mainWindowFrame 
    case selectedTabIndex 
    case recentSearches 
} 

extension Dictionary where Key : String { 
    public subscript(key: UserDefaultsKey) -> Value? { 
     get { return self[key.rawValue] } 
     set { self[key.rawValue] = newValue } 
    } 
} 

は、これは私がこのような値にアクセスすることを許可:

代わりに、このようなアクセス値を有するの
let dict = userDefaults.dictionaryForKey("SearchPrefs") 
if let recentSearches = dict?[.recentSearches] as? [String] { 
    // Populate "Recent" menu items 
} 

...:

let dict = userDefaults.dictionaryForKey("SearchPrefs") 
if let recentSearches = dict?[UserDefaultsKey.recentSearches.rawValue] as? [String] { 
    // Populate "Recent" menu items 
} 

注:NSUserDefaultsから辞書にアクセスするための文字列リテラルの使用は、あくまで例です。私は実際に辞書キーに列挙型を使用するために自分のやり方から外に出ず、文字列リテラルを使用して辞書自体にアクセスしません。 :-)


とにかく、これは私のニーズのために素晴らしい仕事をしている、そしてそれは読んでより多くの快適NSUserDefaultsを含むコードを保ちました。スウィフト3に私のプロジェクトを移行以来

が、しかし、私は次のエラーを取得しています:

extension Dictionary where Key: String { 
    public subscript(key: UserDefaultsKey) -> Value? { <---- Use of undeclared type 'Value' 
               ~~~~~~ 
     get { 
      return self[key.rawValue] 
     } 
     set { 
      self[key.rawValue] = newValue 
     } 
    } 
} 

私はDictionaryのために生成ヘッダを見て、一般的なKeyValue引数がまだ中に存在していますのDictionary構造体です。そのため、問題の原因がわかりません。

私が気付いていない新しいSwift 3の文法に合わせて、where句を書き直す必要がありますか?または...拡張機能の汎用プレースホルダ型にアクセスできなくなる可能性がありますか?

私はちょうど何をすべきかわかりません!

私のプロジェクトの解決には28の移行エラーしか残っていません。私は実際にスウィフト3を使用するように近づいているので、ポインタが好きです(Unsafeおよび/またはRawでない限り)。

ありがとうございます!

+0

で働いていてはいけませんSwift 2のいずれか...コンクリート型のジェネリックパラメータは、残念なことに具体的な型に制約することはできません。 –

+0

@TimVermeulen私はあなたに同意しますが、私は複数の場所でこの "ハッカー"に頼ってきましたが、それはまだ他の拡張機能(私を引用しないでください)で動作するようです。 「ジェネリック?」のままで、それを動作させるためには、どのように書き直すのでしょうか?私は、 'String'が何らかの空の' StringLike'プロトコルに準拠しているような楽しいことを試してみて、それを一般的な制約として使っていたのを覚えていましたが、私の問題は、プロトコル指向の設計パターンを「適切に」実装することになります。 –

+0

関連する(そして重複する可能性がありますか?)[[下付き文字:文字列の列挙を使用して辞書値にアクセス](http://stackoverflow.com/questions/39499137/subscript-access-my-dictionary-values-with-a-string- – Hamish

答えて

6

具体的なタイプの一般的なパラメータは、具体的なタイプに制約することはできません。つまり、

extension Dictionary where Key == String 

のようなものはコンパイルされません。これは、ジェネリックシステムの制限だし、それがうまくいけば、スウィフトに問題になることはありません4

あり、回避策ががあるが、それはハックビットです:

protocol StringConvertible { 
    init(_ string: String) 
} 

extension String: StringConvertible {} 

extension Dictionary where Key: StringConvertible { 

    subscript(key: UserDefaultsKey) -> Value? { 
     get { return self[Key(key.rawValue)] } 
     set { self[Key(key.rawValue)] = newValue } 
    } 

} 
+0

うわー、ハハ、私は偉大な心が似ていると思います。これはあなたが投稿する直前に私が思いついたものです:{{書式の制約のためにほぼ同じコードが省略されました。 }}そして...これまでのところ、とても良い。私はあなたにチェックマークを与えるよ!ありがとう、ティム! –

+0

'として! Key'はイニシャライザを呼び出さないので、うまくいきません:) –

+0

Touché。私の遊び場で働いていましたが、私は安全のためにあなたの提案を実装します。再び、これを手助けしてくれてありがとう。わずか27のエラーが残った! –