我有一個全局變量的音頻播放器。 什麼是調用構造函數「嘗試」關鍵字的位置差異
do{
audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
}catch {}
當然之前將試字變量初始化
do{
try audioPlayer = AVAudioPlayer(contentsOf: audioURL)
}catch {}
前將試之間的區別2案件上面沒有任何編譯錯誤。 謝謝
我有一個全局變量的音頻播放器。 什麼是調用構造函數「嘗試」關鍵字的位置差異
do{
audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
}catch {}
當然之前將試字變量初始化
do{
try audioPlayer = AVAudioPlayer(contentsOf: audioURL)
}catch {}
前將試之間的區別2案件上面沒有任何編譯錯誤。 謝謝
沒有實際的區別。如said by the language guide(重點煤礦):
當在二元操作的左手側上的表達被標記
try
,try?
,或try!
,該操作員適用於 整個二進制表達式。也就是說,您可以使用括號作爲運營商的應用程序的範圍明確的 。// 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
適用於都表達audioPlayer
和AVAudioPlayer(contentsOf: audioURL)
。獨行表達audioPlayer
不可能這裏拋出一個錯誤 - 因此,在這種情況下try
僅適用於呼叫AVAudioPlayer
的init(contentsOf:)
,這可以拋出。
此推導of the grammar是:
// "try" "audioPlayer" "= AVAudioPlayer(contentsOf: audioURL)"
expression → try-operatoropt prefix-expression binary-expressionsopt
prefix-expression → prefix-operatoropt postfix-expression
postfix-expression → primary-expression
primary-expression → identifier generic-argument-clauseopt
identifier → // matches "audioPlayer" (I'm not going to fully derive this bit further)
binary-expressions → binary-expression binary-expressionsopt
binary-expression → assignment-operator try-operatoropt prefix-expression
prefix-expression → prefix-operatoropt 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-operatoropt prefix-expression
,你可以看,try-operator
可以也出現在這裏的運營商的右側,因此將適用於prefix-expression
- 在這種情況下是AVAudioPlayer.init(contentsOf:)
。
因此,在這兩種情況下,您都會捕獲可能從AVAudioPlayer.init(contentsOf:)
中引發的錯誤。第一個示例僅包含從操作員左側的表達式中拋出錯誤的可能性,它不可能不可能所做的。
使用您感覺更舒適的方式 - 我的個人偏好,以及與try
在語言其他地方的位置更一致的選項是將try
置於右側。
在我看來,這編譯其實是一種錯誤的:
try audioPlayer = AVAudioPlayer(contentsOf: audioURL)
基本上,你正在做的事情,你不應該這樣做,而你就是幸運的,它滑過在這裏編譯。考慮,作爲一個反例,如果audioPlayer
正在這裏宣佈,會發生什麼:
try let audioPlayer = AVAudioPlayer(contentsOf: audioURL) // error
這不編譯和修復,它正確地移動try
其所屬的地方:
let audioPlayer = try AVAudioPlayer(contentsOf: audioURL)
,我建議按照規則,因此,這是你應該使用try
放置正確 - 它修改方法調用可以拋出。它有時可能作爲一個整體工作,但並非總是如此,這是一個不好的習慣。
雖然這是一個稍微不同的東西 - 這是一個約束力。如果你把在看看[語法的常量聲明(https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html#//apple_ref/doc/uid/TP40014097 -CH34-ID355),直到'='右邊的表達式纔有'try'的空間。雖然我同意這些規則是不一致的,並且在rhs上嘗試是可取的:) – Hamish
@Hamish右鍵,我只是試圖灌輸「在開始時嘗試」這個概念,好的。如果我認爲它會有所幫助,我會爲此提出一個錯誤,但我知道它不會。 :) – matt
'try'總是以*表達*(不是方法調用)爲前綴。這就是爲什麼前綴賦值是合法的,該賦值是'()'或'Void'類型的表達式。 'try'不需要立即在表達式的拋出部分前加上。你的例子'let audioPlayer = ...'是一個聲明,所以不能用'try'標記。 –
我會建議第一種情況下嘗試分配和第二次嘗試啓動。但我不確定,只是猜測。 – JuicyFruit