2017-03-09 1 views
3

전 오디오 플레이어의 전역 변수가 있습니다. 변수 초기화"try"키워드의 배치 차이점

do{ 
    try audioPlayer = AVAudioPlayer(contentsOf: audioURL) 
}catch {} 

전에 시도 단어를 배치하고 시도를 배치의 차이는 생성자에게 물론

do{ 
    audioPlayer = try AVAudioPlayer(contentsOf: audioURL) 
}catch {} 

를 호출하기 전에 무엇 두 가지 경우 위에서되지 않은 컴파일 오류가 있습니다. 감사합니다.

+0

나는 첫 번째 경우가 할당을 시도하고 두 번째 시도가 시작되도록 제안합니다. 그러나 나는 잘 모르겠다. – JuicyFruit

답변

5

실제적인 차이는 없습니다.

이진 연산자의 좌측 식은 가 try, try? 또는 try! 표시되어

그 오퍼레이터 가 전체 이진 표현에 적용 said by the language guide (강조 광산)한다. 즉, 괄호를 사용하여 연산자 응용 프로그램의 범위에 대해 명시 적으로 이 될 수 있습니다. 그냥 + 같은

// try applies to both function calls 
sum = try someThrowingFunction() + anotherThrowingFunction() 

// try applies to both function calls 
sum = try (someThrowingFunction() + anotherThrowingFunction()) 

// Error: try applies only to the first function call 
sum = (try someThrowingFunction()) + anotherThrowingFunction() 

는 할당은 바이너리 연산자입니다. 그러므로, 당신은

do{ 
    try audioPlayer = AVAudioPlayer(contentsOf: audioURL) 
}catch {} 

try모두 표현 audioPlayerAVAudioPlayer(contentsOf: audioURL) 적용 말한다. 고독한 표정 audioPlayer가능성이 여기에 오류가 발생 할 수 없습니다 - 따라서이 경우에는 tryAVAudioPlayerinit(contentsOf:), 어떤 던져에 대한 호출에 적용됩니다.

이에 대한 유도 of the grammar은 다음과 같습니다

//   "try"   "audioPlayer"  "= AVAudioPlayer(contentsOf: audioURL)" 
expression → try-operator­opt ­prefix-expression ­binary-expressions­opt 

prefix-expression → prefix-operator­opt ­postfix-expression 
postfix-expression → primary-expression­ 
primary-expression → identifier­ generic-argument-clause­opt 
identifier­ → // matches "audioPlayer" (I'm not going to fully derive this bit further) 

binary-expressions → binary-expression ­binary-expressions­opt 
binary-expression → assignment-operator ­try-operator­opt­ prefix-expression 
prefix-expression → prefix-operator­opt postfix-expression 
postfix-expression → initializer-expression­ // matches AVAudioPlayer(contentsOf: audioURL)

당신은 당신이 사실을 사용하고

do{ 
    audioPlayer = try AVAudioPlayer(contentsOf: audioURL) 
}catch {} 

을 말할 때 그 대입 표현식 has the grammar of :

binary-expression → assignment-operator ­try-operator­opt ­prefix-expression­

당신이 할 수 참조, try-operator이 여기에있는 연산자의 오른쪽에 나타나므로 prefix-expression에 적용됩니다 (이 경우 AVAudioPlayer.init(contentsOf:)).

두 경우 모두 AVAudioPlayer.init(contentsOf:)에서 발생할 수있는 오류를 catch하고 있습니다. 첫 번째 예는 연산자의 왼쪽에있는 표현식에서 오류가 발생할 가능성을 포함합니다. 은 가능하면이 될 수 없습니다.

내 개인적인 취향과 언어의 다른 곳에서 try의 위치와 더 일치하는 옵션은 try을 오른쪽에 붙이면됩니다.내보기에서

+3

위대한 설명. 예외가있는 언어에서 온 사람들은'try'가 longjmp가가는 곳이나 다른 "exception"구현 세부 사항을 표시하는 깊은 의미가 있다고 가정 할 수 있습니다. 신속한 예외는 단순히 '반환'의 멋진 버전이라는 것을 명심하는 것이 유용합니다. 'try'는 컴파일러 나 코드 생성에 아무런 영향을 미치지 않습니다. 프로그래머에게이 코드 블록이 예외를 던질 수 있음을 상기시키는 것은 순수한 것입니다. 컴파일러가'try '가 그 알림을 제공하기에 충분히 가깝다고 느끼면, 행복합니다. : D –

+0

사실 이것은 사실이 아닙니다. 라인의 시작 부분에서'try'가 컴파일되지 않는 상황이 있습니다. 나는 그것이 컴파일한다는 사실은 버그라고 생각한다. – matt

+0

@Hamish, 대단히 감사합니다 !!! – GeRyCh

2

이 컴파일 사실은 버그의 종류 : 기본적으로

try audioPlayer = AVAudioPlayer(contentsOf: audioURL) 

, 당신은 당신이하지 말아야 할 일을하고 있으며, 당신은 과거 슬라이드 것을 단지 운이 좋다 여기 컴파일러. audioPlayer 여기에 선언되고 있다면 무슨 일이 일어날 지, 반례로, 고려 : 하지 않는 컴파일하고 수정 - 그것 올바르게가 속한 곳으로 try 이동

try let audioPlayer = AVAudioPlayer(contentsOf: audioURL) // error 

그건 :

let audioPlayer = try AVAudioPlayer(contentsOf: audioURL) 

따라서 내가 따르는 것이 좋습니다 규칙은 try 배치 을 올바르게 사용해야합니다. - 이는 throw 할 수있는 메서드 호출을 수정합니다. 언제나 과제가 전체적으로 이루어지기는하지만, 항상 그렇지는 않습니다. 습관이 좋지 않습니다.

+0

그건 약간 다른 것입니다 - 그건 바인딩입니다. 상수 선언을위한 [문법] (https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097)을 살펴보십시오. -CH34-ID355),'='의 오른쪽에있는 표현식까지 '시도'할 공간이 없습니다. 규칙이 일관성이 없으며 rhs에서 '시도'하는 것이 더 바람직하다고 생각합니다. – Hamish

+0

@Hamish Right, 나는 단지 "줄의 시작 부분에서"시도해보십시오 "라는 생각을 일반화하지 않으려 고 노력하고 있습니다 _not_ 일반적으로 괜찮아. 나는 그것이 좋은 일을 할 것이라고 생각한다면, 나는 이것에 대한 버그를 제기 할 것이지만 그것이 그렇지 않을 것이라는 것을 나는 안다. :) – matt

+1

'try'는 항상 * 표현식 * 접두사입니다 (메소드 호출이 아닙니다). 그래서'()'또는'Void' 타입의 표현식에 접두사를 붙이는 것이 합법적입니다. 'try'는 표현식의 던지는 부분에 바로 접두어를 붙일 필요가 없습니다. 귀하의 예제'let audioPlayer = ...'는 선언이므로'try'로 표시 할 수 없습니다. –