2017-11-01 4 views
2

カスタムパターンマッチングを作成しようとしています。これにより、エラーを切り替えてエラーコードと照合できます。カスタムパターンマッチングが失敗しました。 'Enum case is not typeメンバではありません。'

enum ErrorCode: Int { 
    case notSoDumb 
    case dumbError 
} 

let myError = NSError(domain: "My domain", code: ErrorCode.dumbError.rawValue, userInfo: nil) 

func ~=(pattern: ErrorCode, value: NSError) -> Bool { 
    return (ErrorCode(rawValue: value.code) == pattern) 
} 

switch myError { 
case ErrorCode.notSoDumb: 
    print("Not a dumb error") 
case ErrorCode.dumbError: 
    print("Super dumb error") 
default: 
    print("No matches!") 
} 

私のswitch文の最初のケースはEnum case 'notSoDumb' is not a member of type 'NSError'の誤差があります。以下の例を参照してください。私は整数でErrorCode列挙型を置き換える(およびInt sおよびNSErrorのに合わせて、私のカスタム~=オペレータを更新すると、すべてが正常に動作し

+0

、あなたはこのエラーを取得します、NSErrorインスタンスであるmyErrorとIntを比較すると、このようなエラーにつながるはずです...あなたの主な目的は何ですか? –

+1

これは既知のバグです:https://bugs.swift.org/browse/SR-1121最初に一時的な作業に割り当てる(たとえば、 'not notSoDumbErrorCode = ErrorCode.notSoDumb'と' case notSoDumbErrorCode: ')。 – Hamish

+0

@ハミッシュここで問題点を教えてください。私は、上記のスイッチステートメントに基づいて、そのようなエラーを生成する必要がありますと仮定... –

答えて

3

これは、パターンマッチングでa known bugenumとの例である;。コンパイラが間違って、それは常にだということを前提としてい。enumeration case patternではなくexpression patternで作業

を固定するまで、「表現パターンモード」にコンパイラを強制するための一つの方法は、最初のケースの一時をバインドすることです:

let notSoDumbErrorCode = ErrorCode.notSoDumb 
let dumbErrorCode = ErrorCode.dumbError 

switch myError { 
case notSoDumbErrorCode: 
    print("Not a dumb error") 
case dumbErrorCode: 
    print("Super dumb error") 
default: 
    print("No matches!") 
} 

しかし、これはかなりclunkyです。おそらくより良い回避策は、むしろenumよりも静的メンバとstructを使用することです:これはまた、あなたが(それはよりオープン列挙型のように振る舞う)以降のラインの下の拡張機能を経由して、追加のエラーコードを追加することができます

import Foundation 

struct ErrorCode : Equatable, RawRepresentable { 

    let rawValue: Int 

    static let notSoDumb = ErrorCode(rawValue: 0) 
    static let dumbError = ErrorCode(rawValue: 1) 
} 

let myError = NSError(domain: "My domain", 
         code: ErrorCode.dumbError.rawValue, 
         userInfo: nil) 

func ~=(pattern: ErrorCode, value: NSError) -> Bool { 
    return value.code == pattern.rawValue 
} 

switch myError { 
case ErrorCode.notSoDumb: 
    print("Not a dumb error") 
case ErrorCode.dumbError: 
    print("Super dumb error") 
default: 
    print("No matches!") 
} 

init(rawValue:)から妥当性検査を取り除きますが、それは望ましいかもしれないし、望ましくないかもしれません(あなた自身でもinit?(rawValue:)を実装することができます)。

または、as you say in your comment、あなたはenumを使用してスティックが、代わりにパターンが「表現パターンモード」にコンパイラに強制的に一致したときに、中間関数呼び出しを使用することができます明らかに

enum ErrorCode : Int { 
    case notSoDumb 
    case dumbError 
} 

// ... 

func identity<T>(_ t: T) -> T { return t } 

switch myError { 
case identity(ErrorCode.notSoDumb): 
    print("Not a dumb error") 
case identity(ErrorCode.dumbError): 
    print("Super dumb error") 
default: 
    print("No matches!") 
} 
関連する問題