2014-09-22 3 views
6

에서 유형을 추론 할 수 없습니다 - 'Hashable'을 입력하기 위해 표현식의 타입 '($ T6, (($ T9) -> ($ T9) -> $ T8) -> (($ T9) -> $ T8) -> $ T8)스위프트 내가 사전에 배열을 변환 겉으로는 합법적 인 기능을 가지고 상황

이상하게도 암묵적 반환을 사용하는 경우 :

let dict = arrayToDictionary([1, 2, 3], { val in val }) 

또는 속기 :

let dict = arrayToDictionary([1, 2, 3], { $0 }) 

그냥 잘 작동합니다. 왜?

+0

'DICT = arrayToDictionary ([1, 2, 3], {발에서 발을})하자'(꺼내서' return')도 잘 작동하는 것 같습니다. –

+0

그리고 낯선 사람이라도 'return'을 'Int'로 명시 적으로'val'을 명시 적으로 정의하고 있습니다 :'let dict = arrayToDictionary ([1, 2, 3], {(val : Int) in return val})' 'NSNumber'는 'Int'의 하위 유형이 아닙니다. 'return'을 다시 사용하면 여전히 작동합니다. –

+0

이것은 컴파일러 버그처럼 보입니다. 나는 그것을보고하는 것이 좋습니다. 너무 일찍 끝나고 형식 검사기가 만족스럽지 않은 상황에서 어떤 최적화가 진행되고 있습니다. –

답변

2

이 질문은 실제로 Apple의 컴파일러 엔지니어가 대답 할 수 있습니다. 그리고 위의 주석 자마다 버그로 간주 될 수 있고 /해야하지만 분명히 축약 구문의 한 구멍입니다. 이러한 질문에 대해서는 devforums에 게시하여 좋은 결과를 얻었습니다.

비록 여러 줄이 있거나/return 키워드를 사용해야 할 때마다 반환 유형 또는 캡처 할 값의 유형을 명시 적으로 정의해야한다는 간단한 규칙이 있습니다. 이 제한은 컴팩트/퇴화의 경우, 하나의 종료 지점 (val in val) 만 보장된다는 사실 때문에 return 키워드를 사용할 때 여러 개의 반환 지점을 가질 수 있습니다. 후자의 경우 한 줄에 Int를 반환하고 return 1을 입력하고 nil을 다른 행에 반환 할 수 있습니다. 이 경우, 컴파일러가 가정을 명백하게하기 위해 불평하는 것이 합리적 일 것입니다. 간단히 말해서, 이것은 컴파일러에서 더 정교한 타입 추론을 필요로 할 것이고, 아직 그것에 도달하지 않았을 수도 있습니다.

그래서 TL, DR, 나는 이것을 버그로보고하는 제안에 동의하며, 그 사이에 클로저에서 리턴 유형을 지정하십시오. 당신이 진술 한 것처럼 컴파일러가 올바른 유형을 추론 할 수있는 충분한 컨텍스트를 가지고 있지만 요점은 여전히 ​​남아 있습니다.

주, 그것은 당신의 예뿐만 아니라, 이러한 경우도 작동 :

// inferring var dict as a context for lines below 
var dict = arrayToDictionary([1, 2, 3], { val in val }) 

// dict is already defined, so this works: 
dict = arrayToDictionary([1, 2, 3], { val in return val }) 

// explicit final type, compiler infers backwards 
let d2:Dictionary<Int, Int> = arrayToDictionary([1, 2, 3], { val in val }) 

// explicit return type, compiler infers "forewards" 
let d3 = arrayToDictionary([1, 2, 3], { val -> Int in return val }) 
관련 문제