Swift三元运算符编译错误

Gru*_*kes 5 swift

为什么会产生错误,应该如何编写?

    let x = 5
    let y = 4
    var z:Int
    x < 4 ? z = 6 : z = 8
Run Code Online (Sandbox Code Playgroud)

错误是"找不到<接受提供的参数的<的重载"

ois*_*sdk 8

您的三元运算符不在那里工作的原因是因为各种中缀运算符的优先级.您可以在此处查看运算符优先级列表.如果你看,你会发现底部的操作符通常放在较大的代码块之间.优先级越高,它将更紧密地限制在​​其左侧(或右侧)的表达式.因此,您通常希望您的=运算符具有非常低的关联性,因此在表达式中:

let x = 2 + 3
Run Code Online (Sandbox Code Playgroud)

+遗嘱之前,它将抓住它两侧的两个操作数=,因此它解析为:

let x = (2 + 3)
Run Code Online (Sandbox Code Playgroud)

而不是像:

(let x = 2) + 3
Run Code Online (Sandbox Code Playgroud)

哪个不太有意义.

三元条件运算符的优先级为100,而=运算符的优先级为90.因此在您的示例中,当您得到此值时:

x < 4 ? z = 6 : z = 8
Run Code Online (Sandbox Code Playgroud)

关联性如下:

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
Run Code Online (Sandbox Code Playgroud)

因为三元运算符的优先级高于赋值运算符的优先级,它会"抓取"它z,然后,当它找到=它时,它会变得混乱.编译器看到的内容如下所示:

if (x < 4) { z = 6 } else { z } = 8... // Compiler has a hissy fit
Run Code Online (Sandbox Code Playgroud)

那么你如何解决它?

x < 4 ? (z = 6) : (z = 8) // x < 4 ? z = 6 : (z = 8) works as well
Run Code Online (Sandbox Code Playgroud)

括号使关联性显式化.为什么它首先以这种方式工作?好吧,通常你使用三元运算符将其解析为表达式(就像在@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 }
Run Code Online (Sandbox Code Playgroud)

我希望这有所帮助,也是有道理的.(我可能已经把我的一些优先解释错了,我发现它很混乱)

事实证明,我确实得到了一些错误的优先解释.如果我的解释是正确的,这将不起作用:

x < 4 ? z = 6 : (z = 8)
Run Code Online (Sandbox Code Playgroud)

但确实如此!事实证明,优先问题发生运营商之后,而不是之前.(我在上面解释一下)

此外,带花括号的实际if语句本身不会解析为表达式.所以这不起作用:

let z = if (x < 4) { 6 } else { 8 }
Run Code Online (Sandbox Code Playgroud)