2014-06-22 4 views
6

유형 주조 제네릭 :애플 스위프트 : 나는 일반적인 유형을 포함하는 배열을 좀 스위프트 코드를 쓰고 있어요

let _data: Array<T> = T[]() 

나중에 내 코드에서 나는 배열에 저장된 유형을 결정해야합니다. documentation에 설명 된 형식 캐스팅 기술을 사용해 보았습니다 (generics에는 사용되지 않았지만).

switch self._data { 
case let doubleData as Array<Double>: 
    // Do something with doubleData 
case let floatData as Array<Float>: 
    // Do something with floatData 
default: 
    return nil // If the data type is unknown return nil 
} 

컴파일시 다음과 같은 오류에 위의 switch 문 결과 :

  1. While emitting IR SIL function @_TFC19Adder_Example___Mac6Matrix9transposeUS_7Element__fGS0_Q__FT_GSqGS0_Q___ for 'transpose' at /code.viperscience/Adder/src/Adder Library/Matrix.swift:45:3 :0: error: unable to execute command: Segmentation fault: 11 :0: error: swift frontend command failed due to signal (use -v to see invocation) Command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254

누구 내가 특정 작업을 수행하기 위해 실제 유형 내 일반 데이터를 주조하는 방법을 알아?

+0

'있는 그대로 사용 하시겠습니까? '하지만 귀하의 경우에는 컴파일러 버그라고 생각합니다 ... 신고하십시오! – Jack

+1

옵션을 시도했지만 작동하지 않았습니다. 아마 컴파일러 버그에 동의한다. 그것은 제네릭에 관해서 본 주먹 하나가 아닙니다 ... – nalyd88

답변

1

것은 당신이 버튼의 배열이 있다고 가정 :

let viewsAreButtons = views is [NSButton] // returns true 
let buttonsForSure = views as! [NSButton] // crashes if you are wrong 
let buttonsMaybe = views as? [NSButton] // optionally set 

다음과 같이 사용하려고하면 아래처럼 마녀 경우 작동하지 않습니다. 컴파일러 (Swift 1.2 Xcode 6.3b1)는 "유형 [NSButton]의 다운 캐스트 패턴을 사용할 수 없습니다."라고 말합니다.

switch views { 
    case let buttons as [NSButton]: 
    println("Buttons") 
    default: 
    println("something else") 
} 

한계라고 부릅니다. 유스 케이스에 레이더 파일을 만드십시오. 스위프트 팀은 실제로 의견을 듣기 위해 솔기를.니다. 실제로 작동 시키려면 패턴 일치 연산자를 직접 정의 할 수 있습니다.

struct ButtonArray { } 
let isButtonArray = ButtonArray() 

func ~=(pattern: ButtonArray, value: [NSView]) -> Bool { 
    return value is [NSButton] 
} 

다음이 작동 :

switch views { 
    case isButtonArray: 
     println("Buttons") // This gets printed. 
    default: 
    println("something else") 
} 

이 놀이터에서보십시오이 경우는 다음과 같이 될 것이다. 희망이 도움이됩니다!

2

는 신속한에서 as 운영자는 아래 객체 캐스트 하는 데 사용할 수있는 C++에서 dynamic_cast 같은입니다.

는 유형 A의 객체 a을 말해봐 및 유형 BA를 입력 동일 또는 BA의 하위 클래스 인 경우에만 당신은 let a as B를 작성할 수 있습니다.

경우에 따라 Array<T>은 항상 Array<Double> 또는 Array<Float>으로 다운 캐스트 될 수 없으므로 컴파일러에서 오류를보고합니다.

간단한 수정으로 변환하는 것입니다 AnyObject 첫째, 및 Array<Double> 또는 Array<Float>에 다음 내리 뜬 : 이러한 캐스트를 사용할 수 있습니다

let views: [NSView] = [NSButton(), NSButton(), NSButton()] 

:

let anyData: AnyObject = self._data; 
switch anyData { 
case let doubleData as? Array<Double>: // use as? operator, instead of as, 
             // to avoid runtime exception 
    // Do something with doubleData 
case let floatData as? Array<Float>: 
    // Do something with floatData 
default: 
    return nil // If the data type is unknown return nil 
+0

도움을 주셔서 감사합니다. 그러나 귀하의 설명이 도움이되었지만 아무 소용이없는 해결책을 시도했습니다.배열 항상 배열 또는 배열 캐스팅 수 있지만 그 스위치 문을 무엇입니까? 그것은 정말로 중요하지 않아야 ... 나는 이것이 컴파일러와의 오류라고 생각하고있다. 또한 As? 연산자는 다른 오류 만 생성합니다. Apple 설명서 (위의 링크 참조)는 As를 사용하지 않습니까? 연산자가 아니라 As 연산자 만 사용합니다. – nalyd88