在 Objective-C 中使用三元运算符 + && 执行赋值和操作?
Posted
技术标签:
【中文标题】在 Objective-C 中使用三元运算符 + && 执行赋值和操作?【英文标题】:Perform an assignment and an operation using a ternary operator + && in Objective-C? 【发布时间】:2012-04-06 08:25:32 【问题描述】:以三重幸福的名义(并且不屑于冗长)......我希望,并且有点惊讶......
BOOL isItOpen = YES;
isItOpen = (isItOpen ? YES : NO); // yes, dumbie, it's open.
工作正常……但是……
isItOpen = (isItOpen ? [it close] && NO : [it open] && YES);
结果为@987654323@
我似乎无法找到一个简单的“是”或“否”,即是否可以有条件地使用 &&
(或 ||
)链接操作,就像在 BASH 或 php 中所做的那样。我尝试了&
和&&
安排的各种组合,但无济于事.. 因为我是C
白痴......但如果这种“这样做的方式”是不可能的,在语言上......还有另一个 - 那是否简洁? (即,没有if
s 参与?)
【问题讨论】:
方法 close 和 open 必须返回一个 BOOL 值才能使其工作 @phix23: 或者可以隐式转换为 bool 的东西。 【参考方案1】:您遇到的差异是由于 Objective-C 具有:
(a) 不返回值的真实过程(无效函数/方法);和 (b) 比 PHP 更强大的类型系统
在您的示例中,主要问题是 (a) - 您正在调用返回 nothing 的方法,而 nothing 不是布尔值。
在 PHP 函数中总是返回 something,定义为返回 void 的函数实际上定义为返回一个“无用”值。然而 PHP 会将任何东西转换成任何东西(并且这样做不一致,以增加“乐趣”),因此“无用”值具有布尔值 - 尽管这可能取决于月相 ;-) 此功能确实意味着您可以可靠地链接一个“void”函数 after 一个返回值的函数 - <expr convertible to boolean> && <"void" function>
将在 PHP 中工作(但生成的布尔值是任意的)。同样的事情在 Objective-C 中不起作用(不要尝试用逗号运算符修复它,该运算符存在隐藏的陷阱)。
因此,只要您坚持使用返回布尔值或隐式或显式可转换为布尔值的类型的函数/方法(例如,指针类型 nil
为 false,其他值为 true;对于整数类型,0 为 false,其他所有值true)您可以“有条件地链接”操作。您是否应该这样做是一个不同的问题...
附:如果您想混淆,这很简短:
(isItOpen = !isItOpen) ? [it open] : [it close];
这会让大多数人做双重考虑;-)
【讨论】:
所有好的答案,但感谢分析......和简短的解决方案,无论是否建议使用:-)【参考方案2】:只要您在it
上执行的close
和open
方法返回布尔值,您的代码就可以正常工作。否则,没有雪茄。
【讨论】:
或者可以隐式转换为 bool 的东西。 不幸的是,这个函数不是我定义的——它返回void
。【参考方案3】:
C(以及扩展的 C++ 和 Objective-C1)运算符构成 expressions;它们旨在评估一个值,而不是控制程序流。
所以虽然?:
、&&
和||
都提供short-circuit evaluation 的参数,但您不能使用它们有条件地调用任意函数;2 您应该使用传统控件-flow 构造(即if
)。
您可以使用鲜为人知的comma operator 来实现此目的,但我强烈建议您不要,因为它非常单调且难以阅读.例如:
isItOpen = condition ? (func1(), NO) : (func2(), YES);
-
其实我不懂Objective-C。众所周知,这是可能的!
“任意”是指返回
void
的函数,或者在&&
和||
的情况下不能隐式转换为bool
的类型,或者在这种情况下是不匹配的类型的?:
。
【讨论】:
不是为在三元运算符中使用而设计的,或者不在任何地方使用?例如,isItOpen = YES && [it open];
也不起作用吗?似乎是一种基本能力(根据值或先前值或操作的状态链接简单操作),不是吗?
@alexgray:是的,所有“短路”运算符(?:
、&&
、||
)都是如此。【参考方案4】:
如果你想使用三元运算符,你可以这样做:
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;
按照优先顺序,我建议您使用代码的第三个版本,然后是第二个,然后是第一个。
【讨论】:
我看到@OliCharlesworth 也建议使用逗号运算符。您可以像这样使用他的建议isItOpen = isItOpen ? ([it close], NO) : ([it open], YES);
但这相当于我的答案中的第一个版本,同样不推荐。
这些是很好的解决方案(我的问题)。至于您的建议.. 虽然我喜欢 Objective C(和 Objective-C 程序员),但我对它的“垂直”程度感到畏缩。 (不是 Apple 让我们购买了所有这些宽屏显示器吗?)如果您可以在 1 行,vs. 5 上说些什么……我说做……但是,您的风格警告很受欢迎, 并适当注明。以上是关于在 Objective-C 中使用三元运算符 + && 执行赋值和操作?的主要内容,如果未能解决你的问题,请参考以下文章