Co oznacza znak zapytania i dwukropek (?: Operator potrójny) w celu-c?

270

Co oznacza ten wiersz kodu?

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

?I :mylić mnie.

danielreiser
źródło
1
Jest to trójskładnikowy operator „ jeśli-to-jeszcze”
Klaus Byskov Pedersen
3
Pamiętaj, że powinien to być znak zapytania, a nie cudzysłów.
clahey,
6
Wydaje się, że kompilator także pozwala variable ?: anotherVariable, co to oznacza?
Tony
15
Trójskładnik bez pierwszego elementu oznacza to samo co(valOrVar != 0) ? valOrVar : anotherValorvar
Scott Lahteine

Odpowiedzi:

430

To jest operator trójskładnikowy (Cel-C jest nadzbiorem C):

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

jest semantycznie równoważny z

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

Trójka bez pierwszego elementu (np. variable ?: anotherVariable) Oznacza to samo co(valOrVar != 0) ? valOrVar : anotherValOrVar

Barry Wark
źródło
28
(aktualizacja: Fuj! Reposting jako odpowiedź.) To, co jest tak ważne w trójskładnikowym operatorze, to to, że można go używać w miejscach, których nie mógłby zrobić if-else. tj .: Wewnątrz warunku lub parametru metody. [NSString stringWithFormat: @ „Status:% @”, (statusBool? @ „Zatwierdzony”: @ „Odrzucony”)] ... co doskonale sprawdza się w przypadku stałych preprocesora: #define statusString (statusBool? @ „Zatwierdzony”: @ „Odrzucony”) ... następnie: [NSString stringWithFormat: @ „Status:% @”, statusString] To pozwala uniknąć konieczności używania i zwalniania zmiennych lokalnych we wzorcach if-else. FTW!
Bruno Bronosky,
42
Prawdopodobnie warto wspomnieć, że operator trójskładnikowy bez pierwszego elementu ( ?:) jest jeszcze lepszy w sytuacjach, w których lewa strona jest wyrażeniem, ponieważ ?:uniemożliwia jej ocenę więcej niż jeden raz. Na przykład: [myArray firstObject] ? [myArray firstObject] : @"Hello World";dzwoni firstObjectdwukrotnie (jeśli firstObjectnie zwraca nil), gdzie [myArray firstObject] ?: @"Hello World";daje identyczny wynik, ale nigdy nie dzwoni firstObjectwięcej niż raz.
nhgrif
Wreszcie ~~~~~ Używam tego operatora od wieków (defo mój ulubiony), ale nigdy nie wiedziałem, jak się nazywa. wielkie pytanie zostało już udzielone. Dzięki
Thang Do
Chcę również dodać, że operator trójskładnikowy bez pierwszego elementu ?:jest również nazywany operatorem Elvisa ze względu na podobieństwo emoji do piosenkarza. I oczywiście w tym przypadku, gdy upuszczamy jeden element, nie jest on już operatorem trójskładnikowym, ale operatorem binarnym . Operatory binarne obejmują większość operatorów zazwyczaj używamy podczas programowania ( *, +, -, ^, |, ||, &, >>, etc).
tomacco
179

Jest to operator trójskładnikowy lub warunkowy. Jego podstawowa forma to:

condition ? valueIfTrue : valueIfFalse

Gdzie wartości będą oceniane tylko wtedy, gdy zostaną wybrane.

Sean
źródło
8
Aby wyjaśnić, nie ogranicza się to do wartości. condition ? codeIfTrue : codeIfFalse
Mike S
46

Po prostu logika byłaby

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

Varun Goyal
źródło
4
To jest właściwie najlepsza odpowiedź, ponieważ inne odpowiedzi sugerują, że możesz mieć tylko „wartość” w wyniku, podczas gdy pokazuje to, że możesz w rezultacie umieścić dowolny dowolny kod.
Mike S
36

Opierając się na doskonałym wytłumaczeniu Barry'ego Warka ...

To, co jest tak ważne w trójskładnikowym operatorze, to fakt, że można go używać w miejscach, których nie mógłby wykonać if-else. tj .: Wewnątrz warunku lub parametru metody.

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

... co jest doskonałym zastosowaniem dla stałych preprocesora:

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

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

Dzięki temu nie musisz używać i zwalniać zmiennych lokalnych we wzorcach if-else. FTW!

Richard Bronosky
źródło
14

To tylko zwykły operator trójskładnikowy . Jeśli część przed znakiem zapytania jest prawdziwa, ocenia i zwraca część przed dwukropkiem, w przeciwnym razie ocenia i zwraca część po dwukropku.

a?b:c

jest jak

if(a)
    b;
else
    c;
Brian
źródło
4

Jest to część C, więc nie jest specyficzna dla Celu C. Oto tłumaczenie na ifoświadczenie:

if (inPseudoEditMode)
    label.frame = kLabelIndentedRec;
else
    label.frame = kLabelRect;
Dietrich Epp
źródło
4

To tylko krótka forma napisania instrukcji „jeśli-to-jeszcze”. Oznacza to to samo, co następujący kod:

if(inPseudoEditMode)
  label.frame = kLabelIndentedRect;
else
  label.frame = kLabelRect;
Claus Broch
źródło
2

Przykład operatora trójskładnikowego. Jeśli wartością zmiennej boolean isFemale jest TAK, należy wydrukować „PŁEĆ JEST KOBIETA”, w przeciwnym razie „PŁCI JEST MĘŻCZYZNA”

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

Cel 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.

Dla 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
źródło
2

Ciekawostka, w celu-c, jeśli chcesz sprawdzić null / nil Na przykład:

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

Szybki sposób to zrobić:

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

Następnie możesz zaktualizować go w najprostszy sposób:

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

Ponieważ w celu C:

  1. jeśli obiekt jest zerowy, zwróci false jako wartość logiczną;
  2. Drugi parametr operatora trójskładnikowego może być pusty, ponieważ zwróci wynik po lewej stronie „?”

Powiedzmy, że piszesz:

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

drugi parametr zwraca wartość logiczną, dlatego zgłaszany jest wyjątek.

BananZ
źródło
1

Jest to operator trójskładnikowy, podobnie jak instrukcja if / else.

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

W operatorze trójskładnikowym wygląda to tak: warunek? co zrobić, jeśli warunek jest prawdziwy: co zrobić, jeśli jest fałszywy;

(a > b) ? what to do if true : what to do if false;
cdhw
źródło
2
Doceniam to, że próbujesz przyczynić się do powstania witryny, ale publikowanie odpowiedzi, które po prostu powtarzają to, co już inne odpowiedzi już podałem, jest ogólnie odradzane, ponieważ tylko zagracają pytania.
Chris Hayes
1

Właśnie nauczyłem się czegoś nowego na temat operatora trójskładnikowego. Krótka forma pomijająca środkowy operand jest naprawdę elegancka i jest jednym z wielu powodów, dla których C pozostaje istotny. Do waszej informacji, po raz pierwszy naprawdę się tym zajmowałem w kontekście procedury zaimplementowanej w języku C #, która obsługuje również operatora trójskładnikowego. Ponieważ operator trójskładnikowy znajduje się w C, zrozumiałe jest, że byłoby w innych językach, które są w zasadzie jego rozszerzeniami (np. Objective-C, C #).

David A. Gray
źródło
1

Jak wszyscy to powiedzieli, jest to sposób reprezentowania operatora warunkowego

if (condition){ 
    true 
} 
else {
    false
}

za pomocą operatora trójskładnikowego (condition)? true:false Aby dodać dodatkowe informacje, W trybie szybkim mamy nowy sposób ich reprezentowania za pomocą ??.

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

Który jest podobny do

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

jest równa

if (a>c)?a:c ==> Jest równe if (a>c)?:c

zamiast ?:możemy użyć ??jest szybki.


źródło
1
int padding = ([[UIScreen mainScreen] bounds].size.height <= 480) ? 15 : 55;

znaczy

int padding; 
if ([[UIScreen mainScreen] bounds].size.height <= 480)
  padding = 15;
else
  padding = 55; 
Abo3atef
źródło