Swift ternary Operator Kompilierungsfehler - schnell

Warum erzeugt dies einen Fehler und wie sollte er geschrieben werden?

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

Der Fehler ist "Konnte keine Überlastung für

Antworten:

7 für die Antwort № 1

Das Grund Ihr ternärer Operator arbeitet dort nicht, weil die verschiedenen Infix-Operatoren Vorrang haben. Die Liste der Operator-Prioritäten kann hier angezeigt werden. Wenn Sie nachsehen, werden Sie sehen, dass die Bediener unten sindDie Unterseite sind diejenigen, die normalerweise zwischen größeren Codeabschnitten platziert werden. Je höher der Vorrang, desto enger wird er an die Ausdrücke links (oder rechts) geklemmt. Daher möchten Sie normalerweise Ihre = Operator, um eine sehr geringe Assoziativität zu haben, also in einem Ausdruck wie:

let x = 2 + 3

Das + greift die beiden Operanden auf beiden Seiten Vor das = wird, so beschließt es:

let x = (2 + 3)

anstatt etwas wie:

(let x = 2) + 3

Das macht weniger Sinn.

Der ternäre bedingte Operator hat Vorrang vor 100, während der = Operator hat Vorrang vor 90. Wenn Sie also Folgendes erhalten haben:

x < 4 ? z = 6 : z = 8

Die Assoziativität geht so:

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

Da also der Vorrang des ternären Operators höher ist als der des Zuweisungsoperators, "greift" er den zund dann, wenn es das findet =wird alles verwirrt. Was der Compiler sieht, sieht ungefähr so ​​aus:

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

Wie reparierst du das?

x < 4 ? (z = 6) : (z = 8) // x < 4 ? z = 6 : (z = 8) works as well

Die Klammern machen die Assoziativität explizit.Warum funktioniert es überhaupt so? Normalerweise verwenden Sie den ternären Operator, um ihn in einen Ausdruck aufzulösen (wie in @LeoDabus "Antwort"). In diesem Fall bedeutet seine Assoziativität, dass Sie dies tun nicht brauche die Klammern:

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 }

Ich hoffe das hilft und macht Sinn. (Ich habe vielleicht einige meiner Präzedenzerklärungen falsch verstanden, ich finde es ziemlich verwirrend)

Es stellte sich heraus, dass ich einige meiner Präzedenzerklärungen falsch verstanden habe. Wenn meine Erklärung richtig gewesen wäre, hätte dies nicht funktioniert:

x < 4 ? z = 6 : (z = 8)

Aber es tut! Es stellt sich heraus, dass die Prioritätsprobleme auftreten nach der Betreiber, nicht vorher. (Ich erkläre oben etwas mehr)

Auch die tatsächliche if-Anweisung mit geschweiften Klammern setzt sich zusammen tut nicht zu einem Ausdruck auflösen. Das funktioniert also nicht:

let z = if (x < 4) { 6 } else { 8 }

1 für die Antwort № 2
let x = 5
let y = 4
let z = x < 4 ? 6 : 8

Verwandte Fragen
Speisekarte