คำตอบสั้น ๆ
ผู้ประกอบการทั้งหมด+=
, -=
, *=
, /=
, &=
, |=
... มีเลขคณิตและให้ความคาดหวังเดียวกัน
x &= foo() // We expect foo() be called whatever the value of x
อย่างไรก็ตามผู้ประกอบการ&&=
และ||=
จะเป็นตรรกะและผู้ประกอบการเหล่านี้อาจจะผิดพลาดได้ง่ายเพราะนักพัฒนาจำนวนมากคาดว่าจะได้จะเรียกว่าเสมอในfoo()
x &&= foo()
bool x;
// ...
x &&= foo(); // Many developers might be confused
x = x && foo(); // Still confusing but correct
x = x ? foo() : x; // Understandable
x = x ? foo() : false; // Understandable
if (x) x = foo(); // Obvious
เราจำเป็นต้องทำให้ C / C ++ ซับซ้อนมากขึ้นเพื่อให้ได้คำสั่งลัดมาx = x && foo()
หรือไม่?
เราต้องการทำให้คำสั่งที่คลุมเครือมากขึ้นx = x && foo()
หรือไม่?
หรือเราต้องการเขียนโค้ดที่มีความหมายเช่นif (x) x = foo();
?
คำตอบยาว
ตัวอย่างสำหรับ &&=
หากมี&&=
ตัวดำเนินการรหัสนี้:
bool ok = true; //becomes false when at least a function returns false
ok &&= f1();
ok &&= f2(); //we may expect f2() is called whatever the f1() returned value
เทียบเท่ากับ:
bool ok = true;
if (ok) ok = f1();
if (ok) ok = f2(); //f2() is called only when f1() returns true
รหัสแรกนี้เกิดข้อผิดพลาดได้ง่ายเนื่องจากนักพัฒนาหลายคนคิดว่าf2()
มักจะเรียกว่าf1()
ค่าที่ส่งคืนเสมอ มันเหมือนกับการเขียนbool ok = f1() && f2();
ที่f2()
เรียกเฉพาะเมื่อf1()
ส่งคืนtrue
เท่านั้น
- หากนักพัฒนาต้องการ
f2()
ให้เรียกเมื่อf1()
ส่งคืนเท่านั้นtrue
ดังนั้นโค้ดที่สองด้านบนจึงมีโอกาสเกิดข้อผิดพลาดน้อยกว่า
- อย่างอื่น (ผู้พัฒนาต้องการ
f2()
ให้เรียกเสมอ) &=
ก็เพียงพอแล้ว:
ตัวอย่างสำหรับ &=
bool ok = true;
ok &= f1();
ok &= f2(); //f2() always called whatever the f1() returned value
ยิ่งไปกว่านั้นคอมไพเลอร์จะปรับแต่งโค้ดด้านบนนี้ได้ง่ายกว่าโค้ดด้านล่าง:
bool ok = true;
if (!f1()) ok = false;
if (!f2()) ok = false; //f2() always called
เปรียบเทียบ &&
และ&
เราอาจสงสัยว่าตัวดำเนินการ&&
และ&
ให้ผลลัพธ์เดียวกันหรือไม่เมื่อใช้กับbool
ค่าหรือไม่?
ตรวจสอบโดยใช้รหัส C ++ ต่อไปนี้:
#include <iostream>
void test (int testnumber, bool a, bool b)
{
std::cout << testnumber <<") a="<< a <<" and b="<< b <<"\n"
"a && b = "<< (a && b) <<"\n"
"a & b = "<< (a & b) <<"\n"
"======================" "\n";
}
int main ()
{
test (1, true, true);
test (2, true, false);
test (3, false, false);
test (4, false, true);
}
เอาท์พุท:
1) a=1 and b=1
a && b = 1
a & b = 1
======================
2) a=1 and b=0
a && b = 0
a & b = 0
======================
3) a=0 and b=0
a && b = 0
a & b = 0
======================
4) a=0 and b=1
a && b = 0
a & b = 0
======================
ข้อสรุป
ดังนั้นใช่เราสามารถแทนที่&&
โดย&
สำหรับbool
ค่า ;-)
เพื่อให้ดีขึ้นใช้แทน&=
เราสามารถพิจารณาว่าไม่มีประโยชน์สำหรับบูลีน&&=
&&=
เหมือนกันสำหรับ ||=
ตัวดำเนินการ|=
ยังมีโอกาสเกิดข้อผิดพลาดน้อยกว่า||=
หากต้องการf2()
ให้เรียกนักพัฒนาเมื่อf1()
ส่งคืนfalse
เท่านั้นแทนที่จะเป็น:
bool ok = false;
ok ||= f1();
ok ||= f2(); //f2() is called only when f1() returns false
ok ||= f3(); //f3() is called only when f1() or f2() return false
ok ||= f4(); //f4() is called only when ...
ฉันแนะนำทางเลือกที่เข้าใจได้มากขึ้นต่อไปนี้:
bool ok = false;
if (!ok) ok = f1();
if (!ok) ok = f2();
if (!ok) ok = f3();
if (!ok) ok = f4();
// no comment required here (code is enough understandable)
หรือหากคุณต้องการทั้งหมดในรูปแบบบรรทัดเดียว :
// this comment is required to explain to developers that
// f2() is called only when f1() returns false, and so on...
bool ok = f1() || f2() || f3() || f4();