¿Qué significan el signo de interrogación y los dos puntos (?: Operador ternario) en el objetivo-c?

270

¿Qué significa esta línea de código?

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

El ?y :me confunden.

danielreiser
fuente
1
Es el operador ternario si-entonces-otro
Klaus Byskov Pedersen
3
Tenga en cuenta que esto debería ser un signo de interrogación, no comillas.
clahey
66
El compilador también parece permitir variable ?: anotherVariable, ¿qué significa esto?
Tony
15
El ternario sin primer elemento significa lo mismo que(valOrVar != 0) ? valOrVar : anotherValorvar
Scott Lahteine

Respuestas:

430

Este es el operador ternario C (Objective-C es un superconjunto de C):

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

es semánticamente equivalente a

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

El ternario sin primer elemento (p variable ?: anotherVariable. Ej. ) Significa lo mismo que(valOrVar != 0) ? valOrVar : anotherValOrVar

Barry Wark
fuente
28
(actualización: ¡qué asco! Reposicionar como respuesta). Lo que es tan importante sobre el operador ternario es que puede usarse en lugares que un if-else no puede. es decir: dentro de un parámetro de condición o método. [NSString stringWithFormat: @ "Status:% @", (statusBool? @ "Approved": @ "Rejected")] ... que es un gran uso para las constantes del preprocesador: #define statusString (statusBool? @ "Approved": @ "Rechazado") ... luego: [NSString stringWithFormat: @ "Status:% @", statusString] Esto le ahorra tener que usar y liberar variables locales en patrones if-else. FTW!
Bruno Bronosky,
42
Probablemente valga la pena mencionar que el operador ternario sin el primer elemento ( ?:) es aún mejor en situaciones en las que el lado izquierdo es una expresión, ya que ?:evita que se evalúe más de una vez. Por ejemplo: [myArray firstObject] ? [myArray firstObject] : @"Hello World";llama firstObjectdos veces (si firstObjectno regresa nil), donde [myArray firstObject] ?: @"Hello World";produce el resultado idéntico pero nunca llama firstObjectmás de una vez.
nhgrif
finalmente ~~~~~ He estado usando este operador durante años (definitivamente mi favorito) pero nunca supe cómo se llama. La gran pregunta ya ha sido respondida. Gracias
Thang Do
También quiero agregar que el operador ternario sin el primer elemento ?:también se llama operador Elvis debido a la semejanza emoji con el cantante. Y, por supuesto, en este caso, ya que estamos eliminando un elemento, ya no es un operador ternario sino un operador binario . Los operadores binarios incluyen la gran mayoría de los operadores que suelen utilizar al programar ( *, +, -, ^, |, ||, &, >>, etc).
tomacco
179

Es el operador ternario o condicional. Su forma básica es:

condition ? valueIfTrue : valueIfFalse

Donde los valores solo se evaluarán si se eligen.

Sean
fuente
8
Solo para aclarar, no se limita a los valores. condition ? codeIfTrue : codeIfFalse
Mike S
46

Simplemente, la lógica sería

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

Varun Goyal
fuente
44
Esta es realmente la mejor respuesta porque las otras respuestas implican que solo puede tener un "valor" como resultado, mientras que esto muestra que puede poner cualquier código arbitrario como resultado.
Mike S
36

Sobre la base de la excelente explicación de Barry Wark ...

Lo que es tan importante sobre el operador ternario es que se puede usar en lugares que un if-else no puede. es decir: dentro de un parámetro de condición o método.

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

... que es un gran uso para las constantes del preprocesador:

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

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

Esto le ahorra tener que usar y liberar variables locales en patrones if-else. FTW!

revs Richard Bronosky
fuente
14

Ese es solo el operador ternario habitual . Si la parte anterior al signo de interrogación es verdadera, evalúa y devuelve la parte anterior a los dos puntos; de lo contrario, evalúa y devuelve la parte posterior a los dos puntos.

a?b:c

es como

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

Esto es parte de C, por lo que no es específico de Objective-C. Aquí hay una traducción en una ifdeclaración:

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

Es solo una forma corta de escribir una declaración if-then-else. Significa lo mismo que el siguiente código:

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

Ejemplo de operador ternario. Si el valor de la variable booleana isFemale es SÍ, imprima "GÉNERO ES HEMBRA", de lo contrario, "GÉNERO ES MASCULINO"

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

C objetivo

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.

Para 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
fuente
2

Dato curioso, en el objetivo-c si desea marcar nulo / nulo Por ejemplo:

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

La forma rápida de hacerlo es:

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

Luego puede actualizarlo de la manera más simple:

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

Porque en Objective-C:

  1. si un objeto es nulo, devolverá falso como booleano;
  2. El segundo parámetro del operador ternario puede estar vacío, ya que devolverá el resultado a la izquierda de '?'

Así que digamos que escribes:

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

el segundo parámetro devuelve un valor booleano, por lo tanto, se genera una excepción.

BananZ
fuente
1

Es un operador ternario, como una declaración if / else.

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

En operador ternario es así: ¿condición? qué hacer si la condición es verdadera: qué hacer si es falsa;

(a > b) ? what to do if true : what to do if false;
cdhw
fuente
2
Le agradezco que esté intentando contribuir al sitio, pero generalmente se desaconseja publicar respuestas que simplemente repitan lo que otras respuestas ya han indicado, ya que simplemente llena las preguntas.
Chris Hayes
1

Acabo de aprender algo nuevo sobre el operador ternario. La forma corta que omite el operando del medio es verdaderamente elegante, y es una de las muchas razones por las que C sigue siendo relevante. Para su información, primero entendí realmente esto en el contexto de una rutina implementada en C #, que también es compatible con el operador ternario. Dado que el operador ternario está en C, es lógico pensar que estaría en otros lenguajes que son esencialmente extensiones del mismo (por ejemplo, Objective-C, C #).

David A. Gray
fuente
1

Como todos lo mencionaron, es una forma de representar operador condicional

if (condition){ 
    true 
} 
else {
    false
}

usando el operador ternario (condition)? true:false Para agregar información adicional, en swift tenemos una nueva forma de representarlo usando ??.

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

Que es similar a

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

es equivalente a

if (a>c)?a:c ==> es igual a if (a>c)?:c

en lugar de ?:que podamos usar ??es rápido.


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

medio

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