2012-03-21 42 views
2

在三元幸福的名义(和冗长的不屑)......我希望,和上午有些诧异,....在Objective-C中使用三元运算符+ &&执行赋值和操作?

BOOL isItOpen = YES; 
isItOpen = (isItOpen ? YES : NO); // yes, dumbie, it's open. 

作品很好...但是...

isItOpen = (isItOpen ? [it close] && NO : [it open] && YES); 

结果Invalid operands to binary expression ('void' and 'int')

我似乎无法追查一个简单的是或否,一个人是否可以有条件连锁经营与&&(或||)中说,BASH或PHP像一个做。我尝试过&&&安排的各种组合,但无济于事。因为我是一个C白痴......但如果这种“做到这一点的方式”是不可能的,语言上...还有另一种 - 那就是简洁? (即,没有ifs involed?)

+0

关闭和打开必须返回布尔值,使这项工作 – Felix 2012-03-21 19:01:59

+0

的方法@ phix23:或者可以隐式转换为bool的东西。 – 2012-03-21 19:06:44

回答

3

遇到的差异是由于具有目标C:

的(a)真程序,其不返回值(void函数/方法);和 (b)除PHP

更强的类型系统

在你的榜样的首要问题是(一) - 你在呼唤它会返回什么什么不是一个布尔值的方法。

在PHP函数中,总是返回的东西,定义为返回void的函数实际上定义为返回“无用”值。然而,PHP将几乎任何东西都转换为任何东西(并且为了增加“乐趣”而将其转换为不一致),所以“无用”值具有布尔值 - 尽管这可能取决于月球的相位;-)此功能这意味着你可以可靠地链接一个“无效”功能一个返回值 - <expr convertible to boolean> && <"void" function>将在PHP中工作(但生成的布尔值是任意的)。同样的东西在Objective-C中不起作用(而不是尝试用逗号操作符修复它,这个操作符有隐藏的陷阱)。因此提供了一些函数/方法,它们可以返回一个布尔值,或者一个隐式或显式地转换为布尔值的类型(例如,对于指针类型nil为false,其他值为true;对于整型,0为false,其他都为true )你可以“有条件地链接”操作。不管你应该这样做是不同的问题...

P.S.如果你想成为令人困惑,这是短暂的:

(isItOpen = !isItOpen) ? [it open] : [it close]; 

这将使大多数人做了双重考虑;-)

+0

一切正常的答案,但欣赏分析...和简短的解决方案,无论是使用建议,或不:-) – 2012-04-08 16:30:29

3

C(以及扩展名,C++和Objective-C )运营商表格expressions;它们被设计成评估价值,而不是控制程序流程。

因此,虽然?:&&||都提供了他们的论据short-circuit evaluation,你不能用它们来有条件地调用任意功能; 您应该使用传统的控制流构造(即if)。

可以使用鲜为人知comma operator来实现这一点,但我强烈建议你,因为它的高度unidiomatic,难以辨认。例如: -

isItOpen = condition ? (func1(), NO) : (func2(), YES); 


  1. 其实,我不知道的Objective-C。众所周知,这可能是可能的!
  2. 并以“乱”,我的意思是返回void功能或类型,这不是在&&||,或在?:的情况下,不匹配类型的情况下隐式转换为bool
+0

不适用于三元运算符,或不在任何地方?例如,isItOpen = YES && [它打开];'不工作,要么?看起来像一种这样的基本能力(根据以前的价值或操作的价值或状态链接简单的操作),不是吗? – 2012-03-21 19:01:55

+0

@alexgray:是的,所有的“短路”操作符('?:','&&','||')都是如此。 – 2012-03-21 19:02:47

3

您的代码将只要做工精细,你是在it返回布尔值执行closeopen方法。否则,没有雪茄。

+0

或者可以隐式转换为bool。 – 2012-03-21 19:07:32

+0

不幸的是,这个函数不是我定义的函数,而是返回void。 – 2012-03-21 20:43:21

3

如果你想使用三元运算符,你可以这样做:

isItOpen ? ([it close], isItOpen = NO) : ([it open], isItOpen = YES); 

或者:

isItOpen ? [it close] : [it open]; 
isItOpen = !isItOpen; 

但是,这不是一个良好的编程风格,你应该避免。

以下代码是更可读(至少由C/C++/Objective-C的编程器):

if (isItOpen) 
    [it close]; 
else 
    [it open]; 
isItOpen = !isItOpen; 

按优先顺序排列,我建议您使用代码的第三个版本,然后第二,然后第一个。

+1

我看@OliCharlesworth也建议使用逗号运算符。你可以像这样使用他的建议'isItOpen = isItOpen? ([it close],NO):([it open],YES);'但这相当于我答案中的第一个版本,同样不推荐。 – sch 2012-03-21 19:27:23

+0

这些都是很棒的解决方案(对我的问题)。至于你的建议..虽然我喜欢客观的C(和Objective-C程序员),但我对它的“垂直”感到畏惧。 (是不是苹果公司让我们购买所有这些宽屏显示器?)如果你可以在** 1行上说一些,对比5 ** ......我说要这样做......但是,你的文体警告已经很好地得到了,指出。 – 2012-03-21 19:44:26