Was bedeuten das Fragezeichen und der Doppelpunkt (?: Ternärer Operator) in Ziel-c?

270

Was bedeutet diese Codezeile?

label.frame = (inPseudoEditMode) ? kLabelIndentedRect : kLabelRect;

Das ?und :verwirren mich.

Danielreiser
quelle
1
Es ist der ternäre Wenn-Dann-Sonst- Operator
Klaus Byskov Pedersen
3
Beachten Sie, dass dies ein Fragezeichen und kein Anführungszeichen sein sollte.
Clahey
6
Der Compiler scheint auch zuzulassen variable ?: anotherVariable, was bedeutet das? '
Tony
15
Das Ternär ohne erstes Element bedeutet dasselbe wie(valOrVar != 0) ? valOrVar : anotherValorvar
Scott Lahteine

Antworten:

430

Dies ist der ternäre Operator C (Objective-C ist eine Obermenge von C):

label.frame = (inPseudoEditMode) ? kLabelIndentedRect : kLabelRect;

ist semantisch äquivalent zu

if(inPseudoEditMode) {
 label.frame = kLabelIndentedRect;
} else {
 label.frame = kLabelRect;
}

Das ternäre ohne erstes Element (zB variable ?: anotherVariable) bedeutet dasselbe wie(valOrVar != 0) ? valOrVar : anotherValOrVar

Barry Wark
quelle
28
(Update: Yuck! Reposting als Antwort.) Was am ternären Operator so wichtig ist, ist, dass er an Orten verwendet werden kann, die ein Wenn-Sonst nicht kann. dh: Innerhalb einer Bedingung oder eines Methodenparameters. [NSString stringWithFormat: @ "Status:% @", (statusBool? @ "Genehmigt": @ "Abgelehnt")] ... was eine großartige Verwendung für Präprozessorkonstanten ist: #define statusString (statusBool? @ "Genehmigt": @ "Abgelehnt") ... dann: [NSString stringWithFormat: @ "Status:% @", statusString] Dies erspart Ihnen die Verwendung und Freigabe lokaler Variablen in if-else-Mustern. FTW!
Bruno Bronosky
42
Es ist wahrscheinlich erwähnenswert, dass der ternäre Operator ohne das erste Element ( ?:) in Situationen, in denen die linke Seite ein Ausdruck ist, noch besser ist, da dies ?:verhindert, dass er mehr als einmal ausgewertet wird. Beispiel: [myArray firstObject] ? [myArray firstObject] : @"Hello World";Ruft firstObjectzweimal auf (wenn firstObjectnicht zurückgegeben nil), wobei [myArray firstObject] ?: @"Hello World";das gleiche Ergebnis erzielt wird, jedoch nie firstObjectmehr als einmal aufgerufen wird.
nhgrif
endlich ~~~~~ Ich benutze diesen Operator schon seit Ewigkeiten (defo mein Favorit), wusste aber nie, wie er heißt. Die große Frage wurde nun beantwortet. Vielen Dank
Thang Do
Ich möchte auch hinzufügen, dass der ternäre Operator ohne das erste Element aufgrund der Emoji- Ähnlichkeit mit dem Sänger ?:auch als Elvis-Operator bezeichnet wird . Und natürlich ist es in diesem Fall, wenn wir ein Element löschen, kein ternärer Operator mehr, sondern ein binärer Operator . Binäre Operatoren umfassen die überwiegende Mehrheit der Betreiber wir in der Regel verwenden , bei der Programmierung ( , , , , , , , , etc.). *+-^|||&>>
Tomacco
179

Es ist der ternäre oder bedingte Operator. Die Grundform ist:

condition ? valueIfTrue : valueIfFalse

Wobei die Werte nur ausgewertet werden, wenn sie ausgewählt werden.

Sean
quelle
8
Nur zur Verdeutlichung, es ist nicht auf Werte beschränkt. condition ? codeIfTrue : codeIfFalse
Mike S
46

Einfach wäre die Logik

(condition) ? {code for YES} : {code for NO}

Varun Goyal
quelle
4
Dies ist tatsächlich die beste Antwort, da die anderen Antworten implizieren, dass Sie nur einen "Wert" als Ergebnis haben können, während dies zeigt, dass Sie als Ergebnis beliebigen Code eingeben können.
Mike S
36

Aufbauend auf Barry Warks hervorragender Erklärung ...

Was am ternären Operator so wichtig ist, ist, dass er an Orten verwendet werden kann, die ein Wenn-Sonst nicht kann. dh: Innerhalb einer Bedingung oder eines Methodenparameters.

[NSString stringWithFormat: @"Status: %@", (statusBool ? @"Approved" : @"Rejected")]

... was eine großartige Verwendung für Präprozessorkonstanten ist:

// in your pch file...
#define statusString (statusBool ? @"Approved" : @"Rejected")

// in your m file...
[NSString stringWithFormat: @"Status: %@", statusString]

Dies erspart Ihnen die Verwendung und Freigabe lokaler Variablen in if-else-Mustern. FTW!

Richard Bronosky
quelle
14

Das ist nur der übliche ternäre Operator . Wenn der Teil vor dem Fragezeichen wahr ist, wird der Teil vor dem Doppelpunkt ausgewertet und zurückgegeben, andernfalls wird der Teil nach dem Doppelpunkt ausgewertet und zurückgegeben.

a?b:c

ist wie

if(a)
    b;
else
    c;
Brian
quelle
4

Dies ist Teil von C, daher ist es nicht Objective-C-spezifisch. Hier ist eine Übersetzung in eine ifAussage:

if (inPseudoEditMode)
    label.frame = kLabelIndentedRec;
else
    label.frame = kLabelRect;
Dietrich Epp
quelle
4

Es ist nur eine kurze Form des Schreibens einer Wenn-Dann-Sonst-Aussage. Dies bedeutet dasselbe wie der folgende Code:

if(inPseudoEditMode)
  label.frame = kLabelIndentedRect;
else
  label.frame = kLabelRect;
Claus Broch
quelle
2

Beispiel für einen ternären Operator. Wenn der Wert der booleschen Variablen isFemale YES ist, geben Sie "GENDER IS FEMALE" aus, andernfalls "GENDER IS MALE".

? means = execute the codes before the : if the condition is true. 
: means = execute the codes after the : if the condition is false.

Ziel c

BOOL isFemale = YES;
NSString *valueToPrint = (isFemale == YES) ? @"GENDER IS FEMALE" : @"GENDER IS MALE";
NSLog(valueToPrint); //Result will be "GENDER IS FEMALE" because the value of isFemale was set to YES.

Für Swift

let isFemale = false
let valueToPrint:String = (isFemale == true) ? "GENDER IS FEMALE" : "GENDER IS MALE"
print(valueToPrint) //Result will be  "GENDER IS MALE" because the isFemale value was set to false.
Handiansom
quelle
2

Unterhaltsame Tatsache, in Ziel-c, wenn Sie null / null überprüfen möchten. Zum Beispiel:

-(NSString*) getSomeStringSafeCheck
{
    NSString *string = [self getSomeString];
    if(string != nil){
        return String;
    }
    return @"";
}

Der schnelle Weg dazu ist:

-(NSString*) getSomeStringSafeCheck
{
    return [self getSomeString] != nil ? [self getSomeString] : @"";
}

Dann können Sie es auf einfachste Weise aktualisieren:

-(NSString*) getSomeStringSafeCheck
{
    return [self getSomeString]?: @"";
}

Denn in Objective-C:

  1. Wenn ein Objekt Null ist, gibt es false als Booleschen Wert zurück.
  2. Der zweite Parameter des ternären Operators kann leer sein, da das Ergebnis links von '?'

Nehmen wir also an, Sie schreiben:

[self getSomeString] != nil?: @"";

Der zweite Parameter gibt einen booleschen Wert zurück, daher wird eine Ausnahme ausgelöst.

BananZ
quelle
1

Es ist ein ternärer Operator wie eine if / else-Anweisung.

if(a > b) {
what to do;
}
else {
what to do;
}

Im ternären Operator ist es so: Bedingung? Was tun, wenn die Bedingung erfüllt ist? Was tun, wenn die Bedingung falsch ist?

(a > b) ? what to do if true : what to do if false;
cdhw
quelle
2
Ich weiß es zu schätzen, dass Sie versuchen, einen Beitrag zur Website zu leisten, aber das Posten von Antworten, die einfach wiederholen, was andere Antworten bereits angegeben haben, wird im Allgemeinen nicht empfohlen, da dies nur Fragen durcheinander bringt.
Chris Hayes
1

Ich habe gerade etwas Neues über den ternären Operator gelernt. Die Kurzform, in der der mittlere Operand weggelassen wird, ist wirklich elegant und einer der vielen Gründe, warum C relevant bleibt. Zu Ihrer Information, ich habe mich zuerst im Rahmen einer in C # implementierten Routine, die auch den ternären Operator unterstützt, wirklich damit beschäftigt. Da sich der ternäre Operator in C befindet, liegt es nahe, dass es sich um andere Sprachen handelt, die im Wesentlichen Erweiterungen davon sind (z. B. Objective-C, C #).

David A. Gray
quelle
1

Wie alle darauf hingewiesen haben, ist dies eine Möglichkeit, bedingte Operatoren darzustellen

if (condition){ 
    true 
} 
else {
    false
}

Verwenden des ternären Operators (condition)? true:false Um zusätzliche Informationen hinzuzufügen, haben wir in Kürze eine neue Art der Darstellung mit ??.

let imageObject: UIImage = (UIImage(named: "ImageName")) ?? (initialOfUsername.capitalizedString).imageFromString

Welches ist ähnlich zu

int a = 6, c= 5;
if (a > c) 
{ 
 a is greater
} else {
 c is greater
}

ist äquivalent zu

if (a>c)?a:c ==> Ist gleich if (a>c)?:c

anstatt ?:wir verwenden können ??ist schnell.


quelle
1
int padding = ([[UIScreen mainScreen] bounds].size.height <= 480) ? 15 : 55;

meint

int padding; 
if ([[UIScreen mainScreen] bounds].size.height <= 480)
  padding = 15;
else
  padding = 55; 
Abo3atef
quelle