爲什麼這會產生一個錯誤,它應該如何寫入?Swift三元運算符編譯錯誤
let x = 5
let y = 4
var z:Int
x < 4 ? z = 6 : z = 8
的錯誤是「找不到<接受所提供的參數過載」
爲什麼這會產生一個錯誤,它應該如何寫入?Swift三元運算符編譯錯誤
let x = 5
let y = 4
var z:Int
x < 4 ? z = 6 : z = 8
的錯誤是「找不到<接受所提供的參數過載」
的原因您的三元運算符不工作有原因的優先級的各種中綴操作員。 You can see the operator precedence list here.如果你看,你會發現底層的操作員通常放置在較大的代碼塊之間。優先級越高,它越緊緊地將表達式限制在其左側(或右側)。所以,你通常希望你=
運營商有一個非常低的相關性,所以在這樣的表達式:
let x = 2 + 3
的+
會搶了兩個操作數在它兩側前=
會,所以它解析於:
let x = (2 + 3)
,而不是像這樣:
(let x = 2) + 3
哪個更不合理。
三元有條件的經營者有100優先級,而=
經營者有90優先所以在你的榜樣,當你有這樣的:
x < 4 ? z = 6 : z = 8
的關聯性是這樣的:
x...
x < ...
x < 4 // precedence 130, so resolves
(x < 4)...
(x < 4) ?...
(x < 4) ? z...
(x < 4) ? z = ... // Does not yet resolve. Why? Well, here, the ternary isn't
// really an infix. It is special kind of operator that
// takes something between ? and :. So normal associativity
// doesn't apply. (I'm still experimenting...)
(x < 4) ? z = 6 : ...
(x < 4) ? z = 6 : z // HERE it resolves. The z is grabbed, as the ternary has
// precedence 100, larger than the 90 precedence of the =
((x < 4) ? z = 6 : z) = 8
因此,由於三元運算符的優先級高於賦值運算符的優先級,它會「抓取」z
,然後當它找到=
時,它會全部混淆。什麼編譯器看到看起來是這樣的:
if (x < 4) { z = 6 } else { z } = 8... // Compiler has a hissy fit
那麼如何解決這個問題?
x < 4 ? (z = 6) : (z = 8) // x < 4 ? z = 6 : (z = 8) works as well
括號使關聯明確。爲什麼它首先以這種方式工作?那麼,通常你使用三元運算符來解決它的表達式(就像在@LeoDabus的答案中)。而在這種情況下,其關聯性意味着你不需要括號:
let z = x < 4 ? 6 : 8
let z...
let z = ...
let z = x ...
let z = x < 4 // < has precedence 130, bigger than =
let z = (x < 4) ? // ? has precedence of 100, bigger than =
let z = if (x < 4) { 6 } else { 8 }
我希望幫助,並很有意義。 (我可能得到了一些我的優先解釋錯誤,我發現它很混亂)
原來,我確實得到了一些我的優先解釋錯了。如果我的解釋是正確的,這個就不用工作:
x < 4 ? z = 6 : (z = 8)
但它確實!事實證明,優先級問題發生在之後之後,而不是之前。(我在上面解釋一下)
另外,實際的帶花括號的if語句並不是解析爲表達式。所以這不起作用:
let z = if (x < 4) { 6 } else { 8 }
let x = 5
let y = 4
let z = x < 4 ? 6 : 8
@ LeoDabus的答案是正確的,但僅僅是明確的,爲什麼你選擇不工作的原因是因爲各個運營商的優先級。三元運算符不必解析爲表達式:它也可以只是語句。 'x <4? (z = 6):(z = 8)'例如,將工作。 – oisdk
@oisdk:請把你的評論變成一個答案,因爲這值得我的讚賞。從來沒有意識到三元操作可以這樣使用。 – Antonio