为什么会产生错误,应如何写?
let x = 5 let y = 4 var z:Int x < 4 ? z = 6 : z = 8
错误是“找不到<接受提供的参数的重载”
您的三元运算符在那里不工作的 原因 是由于各种中缀运算符的优先级。您可以在此处查看运算符优先级列表。如果您看一下,会发现底部的运算符通常是放置在较大代码段之间的运算符。优先级越高,它将越紧紧抓住左侧(或右侧)的表达式。因此,您通常希望您的=运算符具有非常低的关联性,因此在类似以下的表达式中:
=
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,然后在找到=时就会感到困惑。编译器看到的内容如下所示:
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 }