为什么这会产生一个错误,它应该如何写入?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