2017-11-01 1 views
2

오류를 전환하고 오류 코드와 일치시킬 수있는 사용자 정의 패턴 일치를 작성하려고합니다.'Enum case is 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들과 NSError들에 맞게 ~= 연산자를 업데이트하는 경우, 모든 작동이 패턴 매칭에 enum 경우와 a known bug입니다

+0

을,이 오류가 발생합니다 , NSError 인스턴스 인'myError'를 Int와 비교하면 에러가 발생합니다 ... 주 목적은 무엇인지 설명해 주시겠습니까? –

+1

이것은 알려진 버그입니다 (https://bugs.swift.org/browse/SR-1121). 먼저 임시 작업에 할당합니다 (예 : 'let notSoDumbErrorCode = ErrorCode.notSoDumb','case notSoDumbErrorCode : '). – Hamish

+0

@Hamish 여기서 문제를 설명해 주시겠습니까? 언급 한 switch 문에 기반하여 그러한 오류가 발생한다고 가정합니다 ... –

답변

3

;. 컴파일러는 잘못이 있다고 가정합니다 항상 .

: 고정까지 오히려 expression pattern

보다 enumeration case pattern 작업 '발현 패턴 모드'로 컴파일러를 강제하는 한가지 방법은 먼저 임시 케이스를 결합하는

그러나 이것은 꽤 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!") 
} 
관련 문제