2017-09-17 9 views
0

메서드에 대한 입력을 특정 프로토콜을 준수하는 인스턴스 목록으로 제한하려고합니다. 필자의 경우에는 메소드를 제어 할 수 없으며 인수를 변경할 수 없습니다. 이 메소드는 특정 유형의 배열을 입력으로 사용합니다. 나는 그 유형에 제약을받는 프로토콜을 만들고 그 프로토콜을 따르는 배열을 전달할 수 있다고 생각했다. 그러나 컴파일러는 나를 허용하지 않을 것입니다.스위프트 : 형식에 제약이있는 프로토콜을 해당 형식의 값으로 변환 할 수 없습니다.

왜 다음 작업을 수행 할 수 없습니까?

protocol SomeProtocol where Self: SomeClass { 

} 

class SomeClass: SomeProtocol { 

} 

func doSomething(input: [SomeClass]) { 

} 

let someClasses: [SomeProtocol] = [SomeClass(), SomeClass()] 

// Cannot convert value of type '[SomeProtocol]' to expected argument type '[SomeClass]' 
doSomething(input: someClasses) 
+0

을 처음. 당신이하고 싶다는 것을 프로토콜 없이도 할 수 있습니다. – Sweeper

+0

'[SomeProtocol]'은'[SomeClass]'의 상위 집합이므로 컴파일러가 실제로 올바른 유형의 인수를 전달하는지 정적으로 확인할 수있는 방법이 없습니다. 여기에 'SomeProtocols'묶음이 있지만 'SomeClass'묶음이 예상됩니다. 이것은 유형 불일치입니다. – pvg

+0

배열에'SomeClass'가 포함되어 있지만 컴파일러가 해당 내용의 런타임 유형이 아닌 인수의 컴파일 타임 유형을 확인하기 때문에 이것이 작동해야한다고 생각할 수 있습니다. 'SomeProtocol'의 서브 타입 인 한 당신이 그 배열에 넣은 것을 신경 쓰지 않습니다. 'someClasses'의 타입은 여러분이 거기에 넣은'SomeProtocol'의 하위 타입이 뭐든간에 ['SomeProtocol']입니다. 함수 호출은 특별히 전달하는 것보다 더 구체적인 형 [SomeClass]을 기대합니다. – pvg

답변

0

doSomething의는 input[SomeClass]입니다하지만 당신은 그것에 [SomeProtocol]을 전달하고 있습니다. SomeProtocolSomeClass이 아니지만 SomeClassSomeProtocol입니다.

let someClasses = [SomeClass(), SomeClass()] 

아니면 매개 변수의 요구 사항을 변경할 수 있습니다 : 컴파일러를 만족시키기 위해, 당신은 단지 [SomeClass]someClasses의 유형을 변경해야하는의 프로토콜을 사용하는 점은 무엇

func doSomething(input: [SomeProtocol]) 
+0

고마워,하지만 문제는 내가 구현을 소유하지 않기 때문에 doSomething에 대한 매개 변수의 요구 사항을 변경할 수없는 구체적인 예입니다. 내 코드 예제는 일반적인 문제를 강조하기위한 것이고 실제 시나리오에서는 someClasses를 제한하는 프로토콜을 사용하고 있습니다. 나는'WhereProtocol'을'SomeClass'에'where' 절이 작동하지 않는 이유를 이해하려고 노력하고있는 것 같습니다. – Darumar