Que signifient le point d'interrogation et le côlon (?: Opérateur ternaire) dans l'objectif-c?

270

Que signifie cette ligne de code?

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

Le ?et :me confondre.

danielreiser
la source
1
C'est l' opérateur ternaire if-then-else
Klaus Byskov Pedersen
3
Notez que cela doit être un point d'interrogation, pas un guillemet.
clahey
6
Le compilateur semble également permettre variable ?: anotherVariable, qu'est-ce que cela signifie?
Tony
15
Le ternaire sans premier élément signifie la même chose que(valOrVar != 0) ? valOrVar : anotherValorvar
Scott Lahteine

Réponses:

430

Il s'agit de l' opérateur ternaire C (Objective-C est un surensemble de C):

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

est sémantiquement équivalent à

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

Le ternaire sans premier élément (par exemple variable ?: anotherVariable) signifie la même chose que(valOrVar != 0) ? valOrVar : anotherValOrVar

Barry Wark
la source
28
(mise à jour: Beurk! Republication comme réponse.) Ce qui est si important à propos de l'opérateur ternaire, c'est qu'il peut être utilisé dans des endroits où un if-else ne le peut pas. ie: à l'intérieur d'un paramètre de condition ou de méthode. [NSString stringWithFormat: @ "Status:% @", (statusBool? @ "Approved": @ "Rejected")] ... ce qui est très utile pour les constantes de préprocesseur: #define statusString (statusBool? @ "Approved": @ "Rejeté") ... alors: [NSString stringWithFormat: @ "Status:% @", statusString] Cela vous évite d'avoir à utiliser et à libérer des variables locales dans des modèles if-else. FTW!
Bruno Bronosky
42
Il convient probablement de mentionner que l'opérateur ternaire sans le premier élément ( ?:) est encore meilleur dans les situations où le côté gauche est une expression, car cela l' ?:empêche d'être évalué plus d'une fois. Par exemple: [myArray firstObject] ? [myArray firstObject] : @"Hello World";appelle firstObjectdeux fois (si firstObjectne revient pas nil), où [myArray firstObject] ?: @"Hello World";produit le résultat identique mais n'appelle jamais firstObjectplus d'une fois.
nhgrif
enfin ~~~~~ J'utilise cet opérateur depuis des lustres (sans doute mon préféré) mais je n'ai jamais su comment il s'appelle. la grande question a maintenant été répondue. Merci
Thang Do
Je veux également ajouter que l'opérateur ternaire sans le premier élément ?:est également appelé l' opérateur Elvis en raison de la ressemblance des emoji avec le chanteur. Et bien sûr, dans ce cas, comme nous supprimons un élément, il ne s'agit plus d'un opérateur ternaire mais d'un opérateur binaire . Les opérateurs binaires comprennent la grande majorité des opérateurs que nous utilisons habituellement lors de la programmation ( *, +, -, ^, |, ||, &, >>, etc.).
tomacco
179

C'est l'opérateur ternaire ou conditionnel. Sa forme de base est:

condition ? valueIfTrue : valueIfFalse

Où les valeurs ne seront évaluées que si elles sont choisies.

Sean
la source
8
Juste pour clarifier, ce n'est pas limité aux valeurs. condition ? codeIfTrue : codeIfFalse
Mike S
46

Simplement, la logique serait

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

Varun Goyal
la source
4
C'est en fait la meilleure réponse car les autres réponses impliquent que vous ne pouvez avoir qu'une "valeur" en conséquence, alors que cela montre que vous pouvez mettre n'importe quel code arbitraire en conséquence.
Mike S
36

S'appuyant sur l'excellente explication de Barry Wark ...

Ce qui est si important à propos de l'opérateur ternaire, c'est qu'il peut être utilisé dans des endroits où un if-else ne peut pas. ie: à l'intérieur d'un paramètre de condition ou de méthode.

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

... ce qui est très utile pour les constantes de préprocesseur:

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

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

Cela vous évite d'avoir à utiliser et à libérer des variables locales dans les modèles if-else. FTW!

Richard Bronosky
la source
14

C'est juste l' opérateur ternaire habituel . Si la partie avant le point d'interrogation est vraie, elle évalue et renvoie la partie avant les deux points, sinon elle évalue et renvoie la partie après les deux points.

a?b:c

est comme

if(a)
    b;
else
    c;
Brian
la source
4

Cela fait partie de C, donc ce n'est pas spécifique à Objective-C. Voici une traduction en une ifdéclaration:

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

C'est juste une forme courte d'écriture d'une instruction if-then-else. Cela signifie la même chose que le code suivant:

if(inPseudoEditMode)
  label.frame = kLabelIndentedRect;
else
  label.frame = kLabelRect;
Brochure Claus
la source
2

Exemple d'opérateur ternaire.Si la valeur de la variable booléenne isFemale est YES, affichez "GENRE EST FEMELLE" sinon "GENRE EST MALE"

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

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

Pour 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
la source
2

Fait amusant, dans objective-c si vous voulez vérifier null / nil Par exemple:

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

Le moyen rapide de le faire est:

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

Ensuite, vous pouvez le mettre à jour de la manière la plus simple:

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

Parce que dans Objective-C:

  1. si un objet est nul, il retournera false comme booléen;
  2. Le deuxième paramètre de l'opérateur ternaire peut être vide, car il retournera le résultat à gauche de '?'

Alors disons que vous écrivez:

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

le deuxième paramètre renvoie une valeur booléenne, donc une exception est levée.

BananZ
la source
1

Il s'agit d'un opérateur ternaire, comme une instruction if / else.

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

En opérateur ternaire c'est comme ça: condition? que faire si la condition est vraie: que faire si elle est fausse;

(a > b) ? what to do if true : what to do if false;
cdhw
la source
2
J'apprécie que vous tentiez de contribuer au site, mais publier des réponses qui répètent simplement ce que d'autres réponses ont déjà déclaré est généralement découragé, car cela encombre les questions.
Chris Hayes
1

Je viens d'apprendre quelque chose de nouveau sur l'opérateur ternaire. La forme courte qui omet l'opérande du milieu est vraiment élégante et est l'une des nombreuses raisons pour lesquelles C reste pertinent. Pour info, j'ai d'abord vraiment compris ce sujet dans le contexte d'une routine implémentée en C #, qui prend également en charge l'opérateur ternaire. Puisque l'opérateur ternaire est en C, il va de soi que ce serait dans d'autres langages qui en sont essentiellement des extensions (par exemple, Objective-C, C #).

David A. Gray
la source
1

Comme tout le monde l'a mentionné, c'est une façon de représenter l'opérateur conditionnel

if (condition){ 
    true 
} 
else {
    false
}

en utilisant l'opérateur ternaire (condition)? true:false Pour ajouter des informations supplémentaires, En rapide nous avons une nouvelle façon de le représenter en utilisant ??.

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

Qui est similaire à

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

est équivalent à

if (a>c)?a:c ==> Est égal à if (a>c)?:c

au lieu de ?:nous pouvons utiliser ??est rapide.


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

veux dire

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