# 39, t 포로토콜 doesn& 자신에게 맞지?
39, t 이 Swift 코드 컴파일하십시오 doesn& 왜?
protocol P { }
struct S: P { }
let arr:[P] = [ S() ]
extension Array where Element : P {
func test<T>() -> [T] {
return []
}
}
let result : [S] = arr.test()
컴파일러는 다음과 같이 말합니다. 유형 'P', 'P' 를 포로토콜 " " 맞지 않습니다. (또는, 이후 버전의 P& # 39, & # 39 를 사용하여 신속하고, "; p& # 39, & # 39 를 준수하는 등 구체적인 유형을 포로토콜. supported." 아닙니다;).
왜안돼요? 이 feels like a hole in the 언어, 잘은 모르겠지만. 나는 이 문제가 있다는 것이 아니라, '도착' 에서 어레이입니다 표시됨과 어레이입니다 of type 프로토콜을 선언하는 것은 이치에 맞지 않는 일을 하면 되죠? 구조체 공급 유형을 정확히 같은 일이 있었다면 생각해봤죠 프로토콜뿐만 도울 수 있는 계층?
116
3
왜 don& # 39, t 프로토콜뿐만 따를 수 있습니까?
맞춰야 할 수 있는 일반적인 경우에 스스로를 프로토콜뿐만 부실 있다. 어떤 일이 벌어질까 정적 포로토콜 홍보하십시오. 이러한 다음과 같습니다.
아마도 수 없다 '는', ' ()' 에 호출하십시오 아펜드네프 [P] 때문에 'P' (이하 '요소') 가 아닙니다, 따라서 구체적인 유형을 就不可能拥有 인스턴스화됩니다. It 콘크리트 입력되었는지 요소, 위치를 확인할 수 있는 어레이에서는 합니다 'p' 유형 준수하는 것을 촉구했습니다.
39 의 it& 비슷한 상황을 정적 메서드 및 속성 요구 사항:
말할 수 없다. ',' SomeGeneric< 측면에서 P>. 우리가 필요한 구체적인 구현을 정적 포로토콜 요구 사항 (표시문 어떻게 있습니다 아니요 구현 '정의' foo () '또는' 표시줄에는 위의 예에서). 우리는 이러한 요구 사항을 구현 'P' 를 정의할 수 있으며, 이러한 구체적인 유형을 따르는 'P' 에 대해서만 정의됩니까 확장명은 - 당신은 여전히 그들을 전화를 할 수 없는 'P' 할 수 있다. 이 때문에 완전히 새로운 유형으로 수 없도록 하고, 그냥 우리 자신을 따르는 충스러웠으니 프로토콜을 사용하여 해당 프로토콜의 정적임 요구 사항, 정보기술 (it), t 는 - 이유는열 doesn& # 39. , T # 39 aren& 인스턴스입니다 프로토콜 요구 사항, 실제 인스턴스입니다 전화를 걸 때 문제가 되는 합니다 협력하였습니다 따르는 프로토콜 (즉, 요구 사항을 구현했습니까 합니다). P ',' 로 입력되었는지 호출하십시오 외면하였나니 요구 사항을 협력하였습니다 인스턴스입니다 앞으로 우리가 할 수 있는 구체적인 type& # 39 의 구현 관용으로충만하신 호출하는 그냥 기본 요건. 그러나 이 경우 어떻게 할 수 있는 특별한 규칙의 예외가 될 수 있는 놀라운 프로토콜뿐만 일반 코드 불일치 취급됩니다. 비록 상황이 너무 수 있다는 것, t '요구' 아소샤테트리프 쁘게 isn& # 39 입니다. (현재) 프로토콜을 사용하여 유형으로 못하도록 합니다. 바꿔야 한다고 할 때 자신을 따르는 프로토콜을 사용하여 너로 유형으로 정적임 요구 사항을 향후 버전의 언어를 할 수 있는 옵션이 있다.
'' 프로토콜뿐만 @objc
사실, 실제로 that& # 39 의 얼마나 정확히 '언어' 프로토콜뿐만 @objc 처리합니다. # 39, don& 때 별로 없는 정적임 요구 사항, 준수하는 것 "이라고 말했다. 다음 컴파일 그냥 그랬다고.
'P', 'T' 따르도록 하는 '배즈' 'P' 는 'T' 할 수 없다 'P' doesn& # 39 경기에서 때문에, 별로 없는 정적임 홍보하십시오. 만약 우리가 더 이상 추가 요구 사항 'P', 예를 들면 정적 컴파일:
그래서 한 '이 문제에 대한 해결 방법 - 너회의 포로토콜' @objc 수 있다. # 39, 대부분의 경우, 이 isn& 부여된 대로 따를 수 없는 이상적인 해결하십시오 너회의 docname 추상형데이터타입 뿐만 아니라, 이에 따라 it 의 실용적인 수업을 하는 런타임용으로 개발하십시오 obj c 같은 플랫폼에서 리눅스 않고 있어 비 사과. 하지만 이 제한은 하는 의심이 & # 39 는 언어 (하나는) 이 이미 주요 원인 없이 itself& # 39, 정적 요구사양에 포로토콜 따릅니다. '대한' @objc 프로토콜뿐만. 주변의 일반 작성된 코드를 컴파일러에 의해 상당히 간편화된. 왜? 그 때문에 '그냥' @objc 포로토콜 입력되었는지 값은 효과적으로 사용하여 클래스를 참조입니다 objc_msgsend 파견 요구 사항이 ''. 측면, 비사양 '뒤집기' 에 운반할 때 더욱 복잡해진 @objc 포로토콜 입력되었는지 값은 테이블을 중심으로 메모리 관리를 위해 가치와 가운데있게하여 모두 그들의 가치를 결정하는 데 랩된 (잠재적으로 간접적으로 저장됩니까) 구축 및 다양한 요구 사항을 요청할 것으로 보인다. 이 때문에 단순한 표현 '유형' P ',' @objc 프로토콜뿐만 대한 값이 같은 프로토콜을 동일한 메모리 표현이 a & # 39, 일반 value& # 39 공유할 수 있습니다. 일부 유형의 일반 자리표시자 'T: , P ' (예상) 보다 쉽게 할 수 있도록 처음에 스위프트 고객팀에 자체 승인. # 39 의 경우도 있지만, 동일한 isn& 비사양 't' 등 일반 값을 갖고, 현재 @objc 프로토콜뿐만 don& 값이거나 포로토콜 가운데있게하여 t # 39 표. 그러나 이 기능을 할 수 있기를 바랍니다 은 의도적 / 는 '같이' 팀 구성원하고만 롤아웃할 비사양 @objc 프로토콜뿐만 의해 확인된 만큼 슬라바 페스토프 [있는 설명을 sr (55)] [1] 이에 대한 쿼리하지 데이터베이스에구성원을 it (프롬프트될 에서 이 질문은). >. 7일 9월 2017년 오후 1 33 셀명 추가되든지 맷 노이부르크 - >. >. 컴파일하십시오 않습니다. >. >. @objc 포로토콜 P {} >. c 형: P {} >. >. func process<, T: P>, (항목: T) - >. T 복귀하십시오 항목설명프로세서} { >. func f (image: P) {이제 처리됩니까: P = 프로세스 (항목 이미지)} >. >. '때문에' @objc 추가 컴파일하십시오. 제거하지 않고 다시 컴파일하십시오 있습니다. >. 스택 오버플로 () 에 비해 우리 중 일부는 이 놀라운 찾기 및 싶어요 >. # 39 에 의한 것인지 알 수 that& 가장자리의 경우 또는 갈레라 컴퍼니. >. >. 7일 9월 2017년 오후 1 53 셀명 추가되든지 슬라바 페스토프 - >. >. # 39 의 it& 의도적인 것은 이 버그는 이 제한 해제 - 관한 것입니다. >. 제가 말했듯이요 it& # 39 의 까다로운 우리는 아직 구체적인 계획은 모든 don& # 39, 없다. 그래서 # 39 는 어느 날 '에 대한 지원을 용이하게 할 it& 생각하신거야 :에서 비사양 @objc' 프로토콜뿐만 잘 알려져 있다. 하지만 현재 어떤 솔루션뀉뀉뀉뀉 발생합니까 비사양 @objc '대한' 프로토콜뿐만?
확장명은 프로토콜을 구현하는 함께 구속
3.1 의 스위프트, 스케쳐내 확장명으로 구속조건으로 주어진 특정 프로토콜을 통해 있는 일반 자리표시자 또는 연관된 유형 반드시 유형이거나 (구체적인 유형을 따르는 것이 아니라 protocol) - 정의할 수 있는 '=' 구속 (constraint) 이 됩니다. 예를 들어, 우리가 할 수 있는 어레이입니다 확장명은 만들 수 있다.
물론 이 이제 우리에게 온 것을 방지할 수 있는 구체적인 유형을 따르는 'P' 이 있는 어레이에서는 호출하십시오 요소. 우리는 이 문제를 해결할 수 있을 때 추가로 단 정의점에 확장자임 '요소: 앞으로 '= P' p ', 그리고 그냥 드래그합니다 확장명은:
그러나 it& # 39 의 가치가 있는 만큼 이를 리셋합니다 O (n) 이 각각의 요소 [P] ',' 변환되게 어레이로의 존재의 컨테이너입니다 작업공간에서 사항박스형 할 것이다. 성능이 중요한 경우 다시 구현 방법을 통해 이 문제를 해결할 수 있는 확장명은 됩니다. , T # 39 이 isn& 완전히 만족할 수 있는 솔루션 - 용이하게 할 수 있는 방법을 익스플레스 a & # 39 는 차기 버전의 언어 포함, 프로토콜 유형 또는 # 39 type& 포로토콜 따릅니다. 구속. 가장 일반적인 방식으로 이를 통해 조속한 이전 3.1 tpc. 롭이에요 fs@snapa 자신의 오토메이티드, [P] ',' 는 단순히 구축하십시오 래퍼 대한 유형을 확장명은 수 있는 방법 (s) 를 정의할 수 있습니다.
반군지역 포로토콜 입력되었는지 인스턴스입니다 제한된 수 있는 일반 자리표시자
다음 고려해보십시오 (아닌 나 '이라는 뜻이다) 상황:
'P' 를 통과할 수 없다 ',' P '를 다케스콘크레테프 (_:)' 로 현재 일반 자리표시자 대체하십시오 수 없다 "고 말했다. P '. # 39 의 let& 살펴 그 중 몇 가지 방법으로 이 문제를 해결할 수 있습니다.
1. 존재의 열기
'P' 가 아닌 '시도중입니다 대체하십시오 T: P ',' P '입력되었는지 와일드링이 자세히 알고 싶다면 우리가 할 수 있는 기본 콘크리트 유형 및 대체하십시오 랩할 파르타잔 그 대신? 이를 위해서는 죄송합니다. 언어 [열기 존재의] [열기] # 39 라는 기능이 있으며, 현재 isn&, 직접 사용자가 사용할 수 없다. 그러나, Swift 열 명 (포로토콜 입력되었는지 값) 가 암시적으로 존재의 액세스하면 그들 (이리에 it 하숙 아웃해야 런타임용으로 개발하십시오 유형 및 접근할 수 있도록 형태로 일반 자리표시자). 우리는 이 사실을 포로토콜 확장명은) 에 'p' 를 활용할 수 있습니다.
그 자체 '일반' 암시적입니다 기록하십시오 자리표시자 확장명은 메서드에서는 데 사용되는 자체 '-' with all behind the scenes 암시적입니다 입력합니다 매개변수입니다 이런 포로토콜 확장명은 멤버. 'P' 를 호출할 때 메서드입니다 포로토콜 입력되었는지 등 구체적인 값을, Swift 하숙 아웃해야 충족하기 위해 '자가' 는 이 기본 유형이 있으며, 일반 자리표시자. 이 때문에 we& # 39, 수 (_:) '을 (를)' 자가 '-' re 호출하십시오 다케스콘크레테프 we& # 39, re 만족할 만한 'T' 을 (를) '자가'. 즉, 이제 기도하라주여
'T' 와 '다케스콘크레테프 (:)' 가 일반 자리표시자 색상에는 불렀으매 달성됨 기본 콘크리트 유형 (이 경우 'S') 가 있다. 참고로 이 isn& # 39 를 준수하는 등, t, 프로토콜뿐만 " themselves", 구체적인 유형을 'P' - # 39, re 대체 we& 아닌 시도하시겠습니까 정적임 추가에는 프로토콜 내에서 이 때 일어나는 것을 요구 사항을 전화하시기 '다케스콘크레테프 (:)'. 자신을 따르는 것을 허용하지 않을 경우 계속 프로토콜뿐만 에서 오프닝 때, 다음 최고의 얼터너티브 약간만이라도 암시적으로 존재의 전달하십시오 시도중입니다 솔리드로 인수를 일반 유형 - 정확히 어떤 일을 했지만, 트램펄린 lionbridge 포로토콜 확장명은 매개변수입니다 효과적으로 없이 그냥 상용구. 그러나 단, t 의 오프닝 존재의 isn& # 39 를 준수하는 일반 해결책을 프로토콜뿐만 않을 것 "이라고 말했다. # 39, t 계약을 이기종 it doesn& 포로토콜 입력되었는지 값뿐만 기본 모음 수 있는 구체적인 유형을 다 다르다. 예를 들어, 고려해야 합니다.
또한 같은 이유로, 여러 'T' 매개변수입니다 일으킬 수 있는 함수를, 매개 변수로 나서야 우리는 같은 유형의 경우 두 개의 'P' 값뿐만 인수만 - 그러나 there& # 39 의 무리라구 컴파일 타임에 보장할 수 있다는 것을 우리는 모두 동일한 기본 콘크리트 유형:. 이 문제를 해결하기 위해 문자 지우개 이용할 수 있다.
2. 지우개 구축하십시오 유형
이를 롭이에요 말한다 는 type 지우개 가 가장 일반적인 해결책은 없는 문제를 프로토콜뿐만 준수하는 것 "이라고 말했다. 그들은 줄 수 있게 한 유형을 구체적으로 포로토콜 입력되었는지 인스턴스입니다 따르는 요구 사항을 전달 인스턴스입니다 의해 해당 프로토콜의 기본 인스턴스입니다. 따라서 let& 전달하는 'P' & # 39 의 구축하십시오 유형: 누진치수의 기입란 # 39 의 임의의 따르는 'P' 는 기본 관용으로충만하신 인스턴스입니다 인스턴스입니다 요구 사항:
이제 그냥 '대신' P '니프 의논하십시오 측면에서':
이제 잠시 고려해보십시오 그냥 왜 그 상자 구축하십시오 했습니다. 지금까지 살펴본 것처럼, Swift 는 이 프로토콜의 초 구체적인 유형을 요구사항뿐 경우의 정적임 홍보하십시오. 'P' 을 구현하는 데 필요한 경우 고려해보십시오 인도하심이라만일 정적 요구 사항 - '그' 니프 가질 것 "이라고 말했다. 하지만 어떻게 해야 이 구축되어 있다. # 39, 임의의 인스턴스들도 'P' re we& 따르는 우리는 여기서 다룰 수 있을지 알 수 없다 - # 39, 구체적인 방법에 대해 해당 don& 추상형데이터타입 정적 요구 사항, 따라서 '이' 니프 구현하십시오 익스플레스 의미 있게 수 없다. 따라서 이 경우에는 전용 솔루션을 정말 유용한) 의 경우 인스턴스입니다 포로토콜 홍보하십시오. 'P' 를 치료할 수 없는 일반적인 경우에, 아직 구체적인 유형을 따르는 'P'. [1]: # 28441 주석문입니다. 페이지 (https://bugs.swift.org/browse/SR-55) =, = com.atlassian.jira.plugin.system.issuetabpanels% 3acomment-tabpanel 28441& 포쿠제드콤멘티드?
[열기]: https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md # 존재의 열기
편집: 18 개월 정도 작업할 것을 포함, 다른 메이저 릴리즈로의 (제공하는 새로운 진단), 그리고 의견을 @AyBayBay makes me want to 재작성할 이 대답. 새로운 진단 입니다.
>. p& # 39, & # 39 를 사용하여 "; p& # 39, & # 39 를 준수하는 등 구체적인 유형을 포로토콜. supported." 않습니다.
실제로 이 모든게 더 많이 있습니다. 이 확장명은:
39 'P', 'P' 요소 = t 적용하십시오 doesn& 때 이후 구체적인 것은 고려하지 않고 있다고 준수를 'P'. (이 경우 it box" 동일팔레트에 "; 솔루션이므로 아래는 여전히 가장 일반적인 솔루션을.)
이전 대답:
39 의 경우, It& strike> <, 또 다른 메타티페스. 정말 하고 싶은 것을 구체적 유형: 대부분의 아닌 사소한 전지전능하심이라 얻을 수 있습니다 [P] ',' isn& # 39 는 콘크리트 유형 (rec.601 can& # 39 는 블록 크기, 메모리 할당 알려진 'P') .< /strike>; (난 don& # 39 의 진정한, 실제로 that& # 39 것 같지는 않다. 무언가를 만들어낼 수 있습니다 'P' nnt 크기 때문에 [it& # 39 의 수행되 통해 우회] (https://developer.apple.com/videos/play/wwdc2016/416/).) 내가 don& # 39 의 경우, 이는 어떤 증거도 없는 것 같습니다 there& # 39 " shouldn& t" # 39;;; 작동합니까. 이 같은 매우 많은 것 같은데, 자신들 중의 한 " doesn& yet" # 39, 빗나갔다. 건이다. (외람되나 it& # 39 의 차이점은 애플은 이러한 경우 무시하려면 얻을 것은 거의 불가능하다.) 사실은, ',' Array< P> 가변적입니다 될 수 있음을 they& # 39 번 유형 (여기서 '어레이입니다 수 없는') 이 있지만, 아직 구현되지 않은 것을 많이 예리한 모서리 및 일부 작업하십시오 방향선이 메타티페스 건으로 집계됐다. # 39, re going to get a # 39, 내가 don& you& " why", 더 나은 것 같지는 않다. 오토메이티드 이상입니다. # 39, t it." 허용하시겠습니까 때문에 doesn& 컴파일러와의 "; (만족시키지 않는, 나도 알아. 내 모든 것을 생명요.)
이 솔루션은 거의 항상 동일팔레트에 창조하셨노 in a box. 우리는 구축하십시오 유형 지우개.
이 때 직접 빠르게 수행할 수 있는 나는한다 작성되지는 결국), 다만 이 상자를 만들어 사용하면 자동으로 공산이 크다. 바로 이러한 재귀 이넘 기록 했다. 그들을 매우 귀찮은 및 제한 전송되었기 기입란 했습니다, 마지막으로 '간접' 같은 일을 할 수 있도록 더 많은 컴파일러에서 자동으로 덧붙였다.
"'콜레스티온티페"' 프로토콜을 확장할 경우 '대신' '어레이입니다 ") 로 구속 및 프로토콜에 의해 구체적인 유형, 이전 코드는 다음과 같이 다시 쓸 수 있습니다.