【问题标题】:Swift ternary operator compilation errorSwift三元运算符编译错误
【发布时间】:2015-09-21 15:16:47
【问题描述】:

为什么会产生错误,应该怎么写?

    let x = 5
    let y = 4
    var z:Int
    x < 4 ? z = 6 : z = 8

错误是“找不到接受所提供参数的

【问题讨论】:

  • @LeoDabus 的回答是正确的,但要明确一点,您的选择不起作用的原因是因为各种运算符的优先级。三元运算符不必解析为表达式:它也可以只是语句。例如,x &lt; 4 ? (z = 6) : (z = 8) 会起作用。
  • @oisdk:请将您的评论变成答案,因为这值得我投票。从来没有意识到可以这样使用三元运算。

标签: swift


【解决方案1】:

您的三元运算符不起作用的原因是因为各种中缀运算符的优先级。 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 }

【讨论】:

  • 这一切当然是对的,但是对于“应该如何写?”这个基本问题,我认为@LeoDabus 有更好的答案。大多数人都会这样写,并期待看到它。
【解决方案2】:
let x = 5
let y = 4
let z = x < 4 ? 6 : 8

【讨论】:

    猜你喜欢
    • 2017-05-12
    • 2012-12-18
    • 1970-01-01
    • 2014-06-16
    • 1970-01-01
    • 2019-01-09
    • 1970-01-01
    • 2018-04-11
    • 2014-05-03
    相关资源
    最近更新 更多