O que o ponto de interrogação e os dois pontos (?: Operador ternário) significam no objetivo-c?

270

O que essa linha de código significa?

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

O ?e :me confundem.

danielreiser
fonte
1
É o ternário if-then-else operador
Klaus Byskov Pedersen
3
Observe que isso deve ser um ponto de interrogação, não aspas.
clahey
6
O compilador também parece permitir variable ?: anotherVariable, o que isso significa?
Tony
15
O ternário sem primeiro elemento significa o mesmo que(valOrVar != 0) ? valOrVar : anotherValorvar
Scott Lahteine

Respostas:

430

Este é o operador secundário (Objective-C é um superconjunto de C):

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

é semanticamente equivalente a

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

O ternário sem primeiro elemento (por exemplo variable ?: anotherVariable) significa o mesmo que(valOrVar != 0) ? valOrVar : anotherValOrVar

Barry Wark
fonte
28
(atualização: Yuck! Reposicionando como resposta.) O que é tão importante sobre o operador ternário é que ele pode ser usado em locais que um if-else não pode. Ex .: Dentro de uma condição ou parâmetro de método. [NSString stringWithFormat: @ "Status:% @", (statusBool? @ "Aprovado": @ "Rejeitado")] ... que é um ótimo uso para constantes do pré-processador: #define statusString (statusBool? @ "Approved": @ "Rejeitado") ... então: [NSString stringWithFormat: @ "Status:% @", statusString] Isso evita que você precise usar e liberar variáveis ​​locais em padrões if-else. FTW!
Bruno Bronosky
42
Provavelmente vale a pena mencionar que o operador ternário sem o primeiro elemento ( ?:) é ainda melhor em situações em que o lado esquerdo é uma expressão, pois ?:impede que seja avaliado mais de uma vez. Por exemplo: [myArray firstObject] ? [myArray firstObject] : @"Hello World";chama firstObjectduas vezes (se firstObjectnão retornar nil), onde [myArray firstObject] ?: @"Hello World";produz o resultado idêntico, mas nunca chama firstObjectmais de uma vez.
Nhgrif
finalmente ~~~~~ Eu uso esse operador há eras (defo meu favorito), mas nunca soube o que é chamado. a grande questão já foi respondida. Obrigado
Thang Do
Também quero acrescentar que o operador ternário sem o primeiro elemento ?:também é chamado de operador Elvis devido à semelhança emoji com o cantor. E, é claro, neste caso, como estamos descartando um elemento, ele não é mais um operador ternário, mas um operador binário . Operadores binários incluem a grande maioria dos operadores geralmente usamos durante a programação ( *, +, -, ^, |, ||, &, >>, etc).
tomacco
179

É o operador ternário ou condicional. Sua forma básica é:

condition ? valueIfTrue : valueIfFalse

Onde os valores serão avaliados apenas se forem escolhidos.

Sean
fonte
8
Apenas para esclarecer, não se limita a valores. condition ? codeIfTrue : codeIfFalse
Mike S
46

Simplesmente, a lógica seria

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

Varun Goyal
fonte
4
Essa é realmente a melhor resposta, porque as outras respostas sugerem que você só pode ter um "valor" como resultado, enquanto isso mostra que você pode colocar qualquer código arbitrário como resultado.
Mike S
36

Com base na excelente explicação de Barry Wark ...

O que é tão importante sobre o operador ternário é que ele pode ser usado em locais que um if-else não pode. Ex .: Dentro de uma condição ou parâmetro de método.

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

... que é um ótimo uso para constantes do pré-processador:

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

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

Isso evita que você precise usar e liberar variáveis ​​locais em padrões if-else. FTW!

Richard Bronosky
fonte
14

Esse é apenas o operador ternário usual . Se a parte antes do ponto de interrogação for verdadeira, ela avalia e retorna a parte antes dos dois pontos, caso contrário, avalia e retorna a parte após os dois pontos.

a?b:c

é como

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

Isso faz parte do C, portanto não é específico do Objective-C. Aqui está uma tradução para uma ifdeclaração:

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

É apenas uma forma curta de escrever uma declaração if-then-else. Significa o mesmo que o seguinte código:

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

Exemplo de operador ternário.Se o valor da variável booleana isFemale for YES, imprima "GENDER IS FEMALE", caso contrário "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.

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

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
fonte
2

Curiosidade, no objetivo-c, se você quiser verificar nulo / zero Por exemplo:

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

A maneira rápida de fazer isso é:

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

Em seguida, você pode atualizá-lo da maneira mais simples:

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

Porque no Objective-C:

  1. se um objeto for nulo, ele retornará false como booleano;
  2. O segundo parâmetro do operador ternário pode estar vazio, pois retornará o resultado à esquerda de '?'

Então, digamos que você escreva:

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

o segundo parâmetro está retornando um valor booleano, portanto, uma exceção é lançada.

BananZ
fonte
1

É um operador ternário, como uma instrução if / else.

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

No operador ternário, é assim: condição? o que fazer se a condição for verdadeira: o que fazer se for falsa;

(a > b) ? what to do if true : what to do if false;
cdhw
fonte
2
Compreendo que você esteja tentando contribuir com o site, mas postar respostas que simplesmente repetem o que outras respostas já declararam geralmente é desencorajado, pois apenas confunde perguntas.
Chris Hayes
1

Acabei de aprender algo novo sobre o operador ternário. A forma abreviada que omite o operando do meio é realmente elegante e é uma das muitas razões pelas quais C permanece relevante. Para sua informação, eu realmente entendi isso no contexto de uma rotina implementada em C #, que também suporta o operador ternário. Como o operador ternário está em C, é lógico que seria em outros idiomas que são essencialmente extensões do mesmo (por exemplo, Objective-C, C #).

David A. Gray
fonte
1

Como todo mundo se referiu, é uma maneira de representar o operador condicional

if (condition){ 
    true 
} 
else {
    false
}

using operator ternary (condition)? true:false Para adicionar informações adicionais, temos rapidamente uma nova maneira de representá-las usando ??.

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

O que é semelhante a

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

é equivalente a

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

em vez de ?:podermos usar ??é rápido.


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

significa

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