2012-03-21 53 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