2016-07-05 6 views
1

제네릭의 유형으로 제한되는 제네릭 클래스의 확장을 시도하고 있습니다. 이것은 내가 일을한다고 생각 코드의 단순화 :일반 오브젝트의 제한된 확장이 유형과 일치하지 않습니다.

struct Thing<T> { 
    var value: T 
} 

struct ContainsStringThing { 
    var stringThing: Thing<String> 
} 

extension Thing where T == String {       // <-- Error location 
    func containedStringThing() -> ContainsStringThing { 
     return ContainsStringThing(stringThing: value) 
    } 
} 

을 그러나, 나는 다음과 같은 오류 메시지가 얻을 :

같은 형태의 요구 사항은 일반적인 매개 변수 'T'제네릭이 아닌

한다을

이 문제를 해결하기 위해 검색 한 결과 유형 대신 확장을 제한하는 프로토콜을 사용하라는 제안을 발견했습니다 : link to article. 이와 나는 결국 것을 수행 한 후 : 이제

protocol StringProtocol { } 

struct Thing<T> { 
    var value: T 
} 

struct ContainsStringThing { 
    var stringThing: Thing<StringProtocol> 
} 

extension Thing where T: StringProtocol { 
    func containedStringThing() -> ContainsStringThing { 
     return ContainsStringThing(stringThing: self)   // <-- Error location 
    } 
} 

은 나를 확장을 제한 할 수 않습니다하지만 다른 오류 메시지가 표시됩니다 :

유형의 값을 변환 할 수 없습니다 '것 < T>'에를 예상 인수 유형 '것 < StringProtocol>'기본적으로 지금은 T는 자체 프로토콜 StringProtocol을 준수하지만, 토륨을 참조 할 때 그것을 모르는 것을 알고

전체 개체 Thing<T>.

해결 방법이 있습니까? 아니면 신속한 제안으로 진화 제안서를 제출해야합니까?

참고 : 모든 코드는 놀이터에서 테스트되며, 복사하여 붙여 넣기 만하면됩니다.

+0

두 번째 코드의 문제점은 T가 StringProtocol을 준수하지 않는다는 것입니다. StringProtocol에 맞는 _no_ 유형이 있기 때문에 불가능합니다! (프로토콜은 일류 유형이 아니며 자체적으로 준수 할 수 없습니다.) – matt

+0

제한된 확장은 T가 StringProtocol (이 경우)을 준수한다는 것을 내부적으로 선언해야합니다. 즉, StringProtocol을 준수하는 유형을 기대하는 항목에 T를 지정할 수 있습니다. 같은 논리에 의해, 오브젝트 의 오브젝트의 형태도, Thing 과 동등 할 필요가 있습니다. 이것을 추론 할 수있는 충분한 정보가 있습니다. – gabriellanata

답변

0

해결 방법으로 self 값을 사용하여 Thing의 새 인스턴스를 만들 수 있습니다. 신속한에서

extension Thing where T: StringProtocol { 
    func containedStringThing() -> ContainsStringThing { 
     return ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value)) 
    } 
} 

2.2 같은 확장 제약 containedStringThing() 함수 값이 입력 StringProtocol 따르는 것은의 인스턴스에 대해 사용할 수 있다는 것을 의미한다. 스위프트 컴파일러는 StringProtocolself.value의 유형을 추론 할 수 있다면

좋을 것이다. 이 경우 ContainsStringThing(stringThing: Thing<StringProtocol>(value: self.value)) 대신 ContainsStringThing(stringThing: self)을 쓸 수 있습니다. 확실히 제안서를 작성해야합니다.

+0

슬프게도 이것은 나를 위해 작동하지 않을 것입니다. 게시물에서 이것은 문제의 단순화라고 말했듯이, Thing 객체는 훨씬 더 복잡하고 내부 값 자체를 전송하는 것만으로는 충분하지 않습니다. – gabriellanata