有什麼好處和弊端:運營商,而不是標準的if-else語句。最明顯的莫過於:優點使用條件的:(三元)運算符
條件:?操作
- 短,直接價值的比較處理和分配
- 似乎並沒有被作爲的if/else靈活時更簡潔構建
標準的if/else
- 可以應用在更多的情況下(如函數調用)
- 通常是不必要的長時間
可讀性似乎每個取決於說法有所不同。在第一次接觸到?:操作符之後的一段時間,我花了一些時間來消化它的工作原理。你會推薦儘可能使用它,或者堅持if/else,因爲我與許多非程序員一起工作?
有什麼好處和弊端:運營商,而不是標準的if-else語句。最明顯的莫過於:優點使用條件的:(三元)運算符
條件:?操作
標準的if/else
可讀性似乎每個取決於說法有所不同。在第一次接觸到?:操作符之後的一段時間,我花了一些時間來消化它的工作原理。你會推薦儘可能使用它,或者堅持if/else,因爲我與許多非程序員一起工作?
我基本上會建議使用它,只有當產生的說法是極短的,代表了簡潔過的if/else相當於在不犧牲可讀性顯著上升。
很好的例子:
int result = Check() ? 1 : 0;
錯誤的例子:
int result = FirstCheck() ? 1 : SecondCheck() ? 1 : ThirdCheck() ? 1 : 0;
我覺得特別有幫助做網站開發的時候,如果我要設置爲在請求發送,如果它被定義,或者某些缺省值賦值的變量,如果它不是。
在web dev中的+1默認值是一個很好的例子,使用三元運算符的好地方 – 2010-07-22 19:53:03
在這種情況下,空合併運算符('??')將更加適合... – 2010-09-01 21:29:53
如果我設置的值,我知道這將永遠是代碼這樣做一條線,我通常使用三元(條件)運算符。如果有機會,我的代碼和邏輯將在未來發生變化,我使用if/else,因爲其他程序員更清楚。
進一步您感興趣的可能是?? operator。
條件運算符的優點是它是一個運算符。換句話說,它返回一個值。由於if
是一個聲明,它不能返回一個值。
一件事使用三元運算符,它是一個表達式不是一個語句時承認。
在類似方案的函數式語言的區別並不存在:
(如果(> AB)AB)
條件:?操作 「似乎不那麼靈活,因爲if/else構造「
在函數式語言中它是。
當在命令式語言中編程時,我在通常使用表達式(賦值,條件語句等)的情況下應用三元運算符。
我建議限制使用三元(?:)運算符來簡化單線賦值if/else邏輯。類似的東西這種模式:
if(<boolCondition>) {
<variable> = <value>;
}
else {
<variable> = <anotherValue>;
}
可以很容易地轉換爲:
<variable> = <boolCondition> ? <value> : <anotherValue>;
我會避免使用三元運算符在需要的if/else的if/else,嵌套情況下的if/else,或者如果/ else分支邏輯導致多行評估。在這些情況下應用三元運算符可能會導致無法讀取,令人困惑和無法管理的代碼。希望這可以幫助。
條件運算符是非常適合短的條件下,這樣的:
varA = boolB ? valC : valD;
我用它偶爾,因爲它需要較少的時間來寫東西呀......不幸的是,這個分支有時可以通過另一個錯過開發者瀏覽你的代碼。另外,代碼通常不是那麼簡短,所以我通常會通過將?和:在不同的行,像這樣:
doSomeStuffToSomething(shouldSomethingBeDone()
? getTheThingThatNeedsStuffDone()
: getTheOtherThingThatNeedsStuffDone());
但是,大的優勢,使用if/else塊(爲什麼我喜歡他們)是,它更容易以後進來,並添加一些額外的邏輯分支,
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else {
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
或添加另一個條件:
if (shouldSomethingBeDone()) {
doSomeStuffToSomething(getTheThingThatNeedsStuffDone());
doSomeAdditionalStuff();
} else if (shouldThisOtherThingBeDone()){
doSomeStuffToSomething(getTheOtherThingThatNeedsStuffDone());
}
那麼,到底,它是關於(較短的使用?)方便您現在對方便你(及其他)以後。這是一個判斷的呼籲......但和所有其他代碼格式問題一樣,唯一真正的規則是要保持一致,並且對於那些必須維護(或評級)代碼的人來說,要有視覺上的禮貌。
(所有代碼眼編譯)
有使用的一些性能優勢?運營商在例如。 MS Visual C++,但這是一個真正的編譯器特定的事情。在某些情況下,編譯器實際上可以優化條件分支。
我最發現自己使用它的情況是因拖欠值,特別是在回報
return someIndex < maxIndex ? someIndex : maxIndex;
這些都是真的,我覺得它不錯的唯一的地方,但對他們我做的。
但如果你正在尋找一個布爾值,這可能有時看起來像一個合適的事情:
bool hey = whatever < whatever_else ? true : false;
因爲它很容易閱讀和理解,但這種想法應該總是扔了更顯而易見的:
bool hey = (whatever < whatever_else);
如果您需要在相同條件下多個分支,使用if:
if (A == 6)
f(1, 2, 3);
else
f(4, 5, 6);
如果需要使用不同的條件下多個分支機構,那麼if語句計數將像滾雪球一樣,你要使用的三元:
f((A == 6)? 1: 4, (B == 6)? 2: 5, (C == 6)? 3: 6);
此外,還可以使用三元運算的初始化。
const int i = (A == 6)? 1 : 4;
這樣做,與如果很凌亂:
int i_temp;
if (A == 6)
i_temp = 1;
else
i_temp = 4;
const int i = i_temp;
你不能把初始化內部的if/else,因爲它的變化範圍。但引用和常量變量只能在初始化時綁定。
我通常選擇的時候我有很多重複的代碼,否則三元操作符。
if (a > 0)
answer = compute(a, b, c, d, e);
else
answer = compute(-a, b, c, d, e);
對於三元運算符,可以用以下方法完成。
answer = compute(a > 0 ? a : -a, b, c, d, e);
三元運算符可以包括一個rvalue內,而如果 - 則 - 否則不能;在另一方面,如果 - 則 - 否則可以執行循環和其它語句,而三元運算只能執行(可能無效)右值。
在一個相關的說明,& &和||運算符允許一些難以用if-then-else實現的執行模式。例如,如果一個人有幾個函數調用,並希望執行一段代碼,如果其中任何失敗,它可以很好地使用& &操作完成。如果沒有該操作員,則需要冗餘代碼,轉到或附加標誌變量。
這是相當多的其他的答案覆蓋,但「這是一個表達」並沒有真正解釋爲什麼會這樣有用...
在像C++和C#語言中,可以定義局部常量(在方法體內)使用它們。這是不可能用傳統的if/then語句,因爲一個const所有的值必須被該單個語句中指定:
const int speed = (shiftKeyDown) ? 10 : 1;
不一樣:
const int speed;
if (shifKeyDown)
speed = 10; // error - can't assign to a const
else
speed = 1; // error
在類似的你可以在其他代碼中嵌入第三個表達式。以及使源代碼更緊湊(和在某些情況下更可讀的結果),也可以使所生成的機器代碼更加緊湊和有效的:
MoveCar((shiftKeyDown) ? 10 : 1);
...可以比具有以產生較少的代碼調用相同的方法兩次:
if (shiftKeyDown)
MoveCar(10);
else
MoveCar(1);
當然,這也是一個更方便,更簡潔的形式(打字,少重複,如果你有,如果複製的代碼塊中的可減少錯誤的機會/其他)。在這樣乾淨的「普通模式」的情況:
object thing = (reference == null) ? null : reference.Thing;
...這簡直是更快的讀取/解析/理解(一旦你習慣了它),比長篇大論的if/else相等的,所以它可以幫助你更快速地「修整」代碼。
當然,僅僅因爲它是有用並不意味着它是在任何情況下使用的最好的事情。我建議只使用它來代替含義較爲明確(或更明確)的短代碼,如果使用更復雜的代碼,或者將三元運算符嵌套在一起,可能會使代碼變得極其困難讀。
@JaminGrey _「這並不意味着,當常量被創建時,它被設置爲10或1。」_你的意思是_does_是什麼意思?不正確的註釋可能會導致對新C++程序員的混淆,而不是您試圖清除的問題;) – Clonkex 2013-11-07 03:02:59
@Clonkex對,謝謝。 =)讓我再試一次: – 2013-11-07 04:38:32
對於未來的讀者來說,通過「* const int speed =(shiftKeyDown)?10:1; *」,這意味着當第一次創建常量*時,它被設置爲10或1.它**並不意味着每次訪問常量時都會執行檢查。 (只是說一個更新的C++程序員感到困惑) – 2013-11-07 04:39:16
一個很酷的用法是:
x = foo ? 1 :
bar ? 2 :
baz ? 3 :
4;
在PHP中注意這一點,三元運算符在PHP中關聯錯誤的方式。從本質上講,如果'foo'是錯誤的,那麼整個事情將評估爲4,而不進行其他測試。 – 2015-03-21 20:16:36
@TomBusby - 哇。還有一個討厭PHP的原因,如果你是一個已經討厭PHP的人。 – 2017-08-07 04:39:03
雖然上面的答案是有效的,和我一起可讀性是重要的同意,有2分還需要考慮的要點:
這使得它特別簡明使用三元:
string GetDrink(DayOfWeek day)
=> day == DayOfWeek.Friday
? "Beer" : "Tea";
如果你有類型T1
和T2
這都可以隱式轉換爲T
,那麼下面呢不工作:
T GetT() => true ? new T1() : new T2();
(因爲編譯器試圖確定三元的類型表達式,並且在T1
和T2
之間沒有轉換。)
另一方面,if/else
版本低於d OES工作:
T GetT()
{
if (true) return new T1();
return new T2();
}
因爲T1
轉化爲T
,所以是T2
有時候,它可以使一個布爾值的分配更容易第一眼就閱讀:
// With
button.IsEnabled = someControl.HasError ? false : true;
// Without
button.IsEnabled = !someControl.HasError;
你已經得到它的要點。 – 2010-07-22 19:51:23
我只在C#中做了一點,但大多數語言都允許在條件運算符內部進行函數調用。C#真的不是嗎?這似乎很奇怪...... – 2010-07-22 19:51:58
@Nicholas Knight:我猜OP意味着你不能這樣做,例如'SomeCheck()? DoFirstThing():DoSecondThing();' - 你必須使用表達式來返回一個值。 – 2010-07-22 19:53:06