为什么会产生错误以及如何编写?
let x = 5
let y = 4
var z:Int
x < 4 ? z = 6 : z = 8
错误是&#34;无法找到&lt;的重载接受提供的参数&#34;
答案 0 :(得分: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
,然后,当它找到=
时,它会变得混乱。编译器看到的内容如下所示:
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 }
答案 1 :(得分:2)
let x = 5
let y = 4
let z = x < 4 ? 6 : 8