在Objective-C中,问号和冒号(?: 三目运算符)代表什么意思?

292

这行代码是什么意思?

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

?: 让我感到困惑。


1
这是三元条件运算符。[if-then-else] (http://www.techotopia.com/index.php/Objective-C_Operators_and_Expressions#The_Ternary_Operator) - Klaus Byskov Pedersen
3
请注意,这应该是一个问号,而不是引号。 - clahey
7
编译器似乎也允许 variable ?: anotherVariable,这是什么意思? - Tony
15
无第一个元素的三目运算符与(valOrVar != 0) ? valOrVar : anotherValorvar意思相同。 - Scott Lahteine
13个回答

454

这是C语言中的三目运算符(Objective-C是C语言的超集):

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

语义上等同于

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

没有第一个元素的三目运算符(例如variable ?: anotherVariable)与(valOrVar != 0) ? valOrVar : anotherValOrVar意思相同。


29
三目运算符的重要之处在于它可以在 if-else 无法使用的地方使用,例如:在条件或方法参数中。[NSString stringWithFormat: @"状态: %@", (statusBool ? @"批准" : @"拒绝")]...这是预处理器常量的一个很好的用法:#define statusString (statusBool ? @"批准" : @"拒绝")...然后:[NSString stringWithFormat: @"状态: %@", statusString]这样可以省去在 if-else 结构中使用和释放本地变量的步骤。胜利! - Bruno Bronosky
46
要说明的是,如果左侧是一个表达式,则不带第一个元素的三元运算符(?:)在某些情况下甚至更好,因为 ?: 可以防止其被评估超过一次。例如:[myArray firstObject] ? [myArray firstObject] : @"Hello World"; 在调用 firstObject 两次(如果 firstObject 不返回 nil 的话),而 [myArray firstObject] ?: @"Hello World"; 产生相同的结果,但永远不会调用 firstObject 超过一次。 - nhgrif
终于~~~~~我已经使用这个运算符很长时间了(绝对是我的最爱),但从未知道它叫什么。现在这个大问题得到了解答。谢谢。 - Thang Do
1
还要补充一点,没有第一个元素?:的三元运算符也被称为Elvis运算符,因为它与歌手的emoji相似。当然,在这种情况下,我们删除了一个元素,它不再是一个三元运算符,而是一个二元运算符。二元运算符包括我们通常在编程中使用的绝大多数运算符(*,+,-,^, |,||, &, >>等)。 - tomacco

189

这是三元条件运算符。它的基本形式为:

condition ? valueIfTrue : valueIfFalse

仅当选择它们时,这些值才会被计算。


10
需要翻译的内容:Just to clarify, it's not limited to values. condition ? codeIfTrue : codeIfFalse为了澄清一下,它不仅限于值。condition ? codeIfTrue : codeIfFalse - Mike S
或者更精确地说,所有三个操作数都是表达式condition_expression ? expression1 : expression2。表达式可以是变量、函数结果,或者它们的组合。 - fbitterlich

68

简单来说,逻辑应该是

(条件) ? {YES代码} : {NO代码}


9
这实际上是最佳答案,因为其他答案暗示你只能得到一个“值”作为结果,而这个答案表明你可以将任何任意代码作为结果。 - Mike S

36

在Barry Wark的出色解释基础上,需要进一步说明的是三元运算符之所以重要,是因为它可以在if-else无法使用的地方使用,例如:在条件或方法参数中。

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

这是预处理器常量的一个很好的用途:

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

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

这可以避免你在if-else模式中使用和释放本地变量。 为胜利而战!


17

这只是一种常见的三元运算符。如果问号前面的部分为真,则评估并返回冒号前面的部分,否则评估并返回冒号后面的部分。

a?b:c

就像

if(a)
    b;
else
    c;

4

这是C语言的一部分,因此不仅限于Objective-C。下面是一个转换为if语句的示例:

if (inPseudoEditMode)
    label.frame = kLabelIndentedRec;
else
    label.frame = kLabelRect;

4

这只是一个简写形式的if-then-else语句。它与以下代码意思相同:

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

3

有趣的事实是,在Objective-C中,如果您想检查null / nil

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

快速的方法是:

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

然后,您可以将其更新为最简单的方式:
-(NSString*) getSomeStringSafeCheck
{
    return [self getSomeString]?: @"";
}

因为在Objective-C中:

  1. 如果一个对象是nil,它将返回false作为布尔值;
  2. 三元运算符的第二个参数可以为空,因为它将返回'?'左侧的结果。

所以假设你写:

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

第二个参数返回一个布尔值,因此会抛出异常。

2
三元运算符示例。如果isFemale布尔变量的值为YES,则打印“GENDER IS FEMALE”,否则打印“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.

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

对于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.

1

正如大家所说,它是表示条件运算符的一种方式

if (condition){ 
    true 
} 
else {
    false
}

使用三元运算符 (condition)? true:false。为了添加额外信息,在Swift中我们有一种新的表示方法,使用??

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

这类似于

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

等同于

if (a>c)?a:c ==> 等同于 if (a>c)??c

在Swift中,我们可以使用??代替?:


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接