2016-08-10 2 views
3

나는 관련 유형의 프로토콜이 : 이제일반 제약

protocol MyProtocol { 
    associatedtype Q 
} 

나는 각 관련된 값으로 Q을 가지고 어디에

enum MyEnum<Q> { 
    case zero 
    case one(MyProtocol) 
    case two(MyProtocol, MyProtocol) 
} 

같은 열거를하고 싶습니다를 관련 유형. 작동하지 않습니다.

enum MyEnum<Q> { 
    case zero 
    case one<P: MyProtocol where P.Q == Q>(P) 
    case two<P1: MyProtocol, P2: MyProtocol where P1.Q == Q, P2.Q == Q>(P1, P2) 
} 

분명히 개별 열거 형 멤버는 자신의 제네릭 제약 조건을 가질 수 없습니다.

내가 생각할 수있는 유일한 것은 이러한 제약 조건을 enum 선언으로 이동하는 것이지만 연결된 형식을 고정합니다. 이것이 내가 원하는 바가 아닌 이유를 보여주기 위해, 내가 할 수 있기를 바란다 :

struct StructA: MyProtocol { 
    typealias Q = Int 
} 

struct StructB: MyProtocol { 
    typealias Q = Int 
} 

var enumValue = MyEnum.one(StructA()) 
enumValue = .two(StructB(), StructA()) 
enumValue = .two(StructA(), StructB()) 

이 제한을 해결할 방법이 있을까요?

+1

좀 더 구체적인 예를 들려 줄 수 있습니까? 그래서'Q'는'MyProtocol'의'associatedtype'의 이름입니다. 또한 그것 자체의 고유 한 타입입니다. – Alexander

+0

@AlexanderMomchliov 'Q'는 고유 한 유형이 아닙니다. 그것은 MyProtocol의'associatedtype'과'MyEnum'의 제네릭 타입이기도합니다. 왜냐하면 관련된 각 값의'MyProtocol' 타입에 관련된'Q' 타입을 제약하기를 원하기 때문입니다. 그게 문제가 해결되면 알려줘. –

+0

오, 그래. 나는 이해한다고 생각해. 그렇다면 영어로 묘사 된대로 정확히 목표는 무엇입니까? – Alexander

답변

2

지우기 유형. 대답은 항상 유형 삭제입니다.

struct AnyProtocol<Element>: MyProtocol { 
    typealias Q = Element 
    // and the rest of the type-erasure forwarding, based on actual protocol 
} 

지금 당신은 지우개가 A Little Respect for AnySequence 참조 유형을 구축하는 방법에 대한 깊은 논의는 그들에게

enum MyEnum<Q> { 
    case zero 
    case one(AnyProtocol<Q>) 
    case two(AnyProtocol<Q>, AnyProtocol<Q>) 
} 

를 사용하는 열거를 만들 수 있습니다

는 당신이 필요로하는 것은 AnyProtocol 유형입니다.

스위프트는 실제 유형 또는 추상 유형으로 PAT (관련 유형이있는 프로토콜)를 논의 할 수 없습니다. 제약 조건 일뿐입니다. 그것을 추상적 인 유형으로 사용하기 위해서 그것을 타입 지우개로 증류해야합니다. 다행히도 이것은 꽤 기계적이며 대부분의 경우 어렵지 않습니다. 그것은 기계적으로 컴파일러가 결국 당신을 위해 일하게 될 것입니다. 그러나 누군가는 상자를 만들어야하고, 오늘은 당신입니다.

+0

고마워요, 롭. 그것은 정말로 내가 듣기를 희망하는 것이 아니지만 완벽하게 그 일을합니다. –

관련 문제