2016-09-26 4 views
0

스위프트 2에서 코드를 마이 그 레이션하려고 할 때 컴파일러에서 이상한 동작이 발생했습니다 (Xcode 8, 스위프트 3) 알아낼 수 없습니다. 튜플로 처리 할 수는 있지만 완전히 확신 할 수는 없습니다.스위프트 3 : 중첩 된 일반 유형

몇 가지 제네릭을 정의하는 일반 클래스가 있습니다. 그 제네릭에, 나 또한 몇 가지 유형 별칭의 설정하고 사용하는 기능을 가지고 : 할당 (let pendingRequest: Request = ...)에

open class GuardPool <Key: Hashable, Resource> { 

    public typealias ResourceCallback = ([Resource]) -> Void 
    public typealias Request = (keys: Set<Key>, cb: ResourceCallback) 
    fileprivate var pendingRequests: [Request] = [] 

    open func request(_ keys: Set<Key>, cb: ([Resource]) -> Void) { 
    let pendingRequest: Request = (keys: keys, cb: cb) 
    pendingRequests.append(pendingRequest) 
    } 
} 

을, 나는이 오류 얻을 :

Cannot convert value of type 'Set<Key>' to specified type 'Set<_>' 

을 나는 알아낼 수 없습니다 이 문제를 해결하는 방법. 컴파일러가 Set의 형식 정보를 인식 할 수없는 것 같습니다.

참고 : 분명히, 클래스는 이것보다 훨씬 큽니다. 300 줄을 삽입하는 대신 관련 코드를 복사하여 붙여 넣었습니다.

답변

0

오류 메시지가 잘못 표시되었습니다. 두 번째 줄에 에게 (불필요한) 명시 적 유형의 주석을 제거하면

let pendingRequest = (keys: keys, cb: cb) 

는 컴파일러는 상태가

실제 문제를 보여
 
error: non-escaping parameter 'cb' may only be called 
note: parameter 'cb' is implicitly non-escaping 

다음 cb 매개 변수 @escaping 때문으로 표시되어야합니다 그것은 속성에 저장되며 request 메서드에서 복귀 한 후 메서드를 호출 한 후 나중에 호출 할 수 있습니다.

open func request(_ keys: Set<Key>, cb: @escaping ([Resource]) -> Void) { 
    let pendingRequest = (keys: keys, cb: cb) 
    pendingRequests.append(pendingRequest) 
} 

스위프트 2에서 클로저는 기본적으로 이스케이프 처리되었으며 과 @noescape으로 표시 될 수 있습니다. 스위프트 3에서 클로저는 기본적으로 실행되지 않으며 과 SE-0103: Make non-escaping closures the default을 비교합니다.

+0

넵 ... 아주 오도 된 오류 메시지였습니다. 나는 그걸 알아 냈고 내 자신의 질문에 대답하려고했지만 당신은 나를 때렸다! 감사! –

+0

40k가 넘는 코드가 작동하기 때문에 이주자는 클로저가'@ 이스케이프 '로 표시되어야하는 곳을 놓쳤습니다. 명시 적 할당은 원래이 pendingRequests.append ((keys : keys, cb : cb))에서 오류가 발생했기 때문에 수행되었습니다. 명시 적으로 입력 된 과제를 추가하면 문제가 해결되지만 계속해서 같은 오류가 발생하기를 바랍니다. 흥미롭게도이 동일한 오류는 중첩 된 유형과 클로저가 튜플에 결합 된 코드의 일부 위치에서 발생했습니다. –