2017-07-08 20 views
0

Optionalキーで辞書を作成するための回避策はありますか?私はこのための適切な解決策が条件付き適合が実装される必要があることを知っていますが、私はその前にオプションがありますか?新しいHashableOptionalenumを作成します:任意のキーの辞書

let dict: [Int?: Int] = [nil: 1] 
// ERROR: type 'Int?' does not conform to protocol 'Hashable' 
+0

ていますか?定義上、 'nil'キーは*値なしを示し、基底型はキー**および**値として非オプション型のみをサポートするので、型は' NSDictionary'に橋渡しすることはできません。 – vadian

+0

@vadianええ、私は「NSDictionary」への出かけは必要ありません。私の使用例は次のとおりです。目的のCランタイムのクラスのクラス階層を構築しています。この辞書は、クラスをそのサブクラスの配列にマップします。ルートクラスは 'class_getSuperclass'から与えられたように" nil "スーパークラスを持っています。 – Alexander

+0

@vadian 'nil'が' NSNull'に橋渡しされるので、NSDictionaryにブリッジすることができます。 – Hamish

答えて

1

ここで私が見つけた1つの回避策です

enum HashableOptional<Wrapped: Hashable> { 
    case none 
    case some(Wrapped) 

    public init(_ some: Wrapped) { 
     self = .some(some) 
    } 

    public init(_ optional: Wrapped?) { 
     self = optional.map{ .some($0) } ?? .none 
    } 

    public var value: Wrapped? { 
     switch self { 
      case .none: return nil 
      case .some(let wrapped): return wrapped 
     } 
    } 
} 

extension HashableOptional: Equatable { 
    static func ==(lhs: HashableOptional, rhs: HashableOptional) -> Bool { 
     switch (lhs, rhs) { 
      case (.none, .none): return true 
      case (.some(let a), .some(let b)): return a == b 
      default: return false 
     } 
    } 
} 

extension HashableOptional: Hashable { 
    var hashValue: Int { 
     switch self { 
      case .none: return 0 
      case .some(let wrapped): return wrapped.hashValue 
     } 
    } 
} 

extension HashableOptional: ExpressibleByNilLiteral { 
    public init(nilLiteral:()) { 
     self = .none 
    } 
} 

をそして、あなたはそうのようにそれを使用することができます:あなたはこれをよろしい

let dict: [HashableOptional<Int>: Int] = [nil: 1] 
+0

個人的には、私は単にラッパータイプを'wrapped?' 'base'プロパティを公開し、オプションの値にアクセスする必要があるときに' key.base'を参照するだけです。 'Optional'には、ラッパー自体(オプションの連鎖、オプションのバインディング、暗黙的なプロモーション、砂糖パターンなど)には複製できないベーキング言語の機能がたくさんあるので、IMOはラッパーとの明確な区別をしています基礎となる値はより一貫したインタフェースを提供します。 – Hamish

+0

@ハミッシュ良い点。ご覧のとおり、マップとフラットマップの追加を省略しました。私は値にアクセスするのはちょっと簡単かもしれないと思うし、ちょうどそれを直接保管するかもしれない。あなたが知っている、私はちょっとあなたがどのタイプでも条件付きバインディングを使用することができない – Alexander