ทำไมไม่มีตัวดำเนินการกำหนดผสมสำหรับตัวดำเนินการเชิงตรรกะ (เช่น ||, && ฯลฯ )


20

ตาม ECMA-262 ซึ่งเป็นส่วนหนึ่ง 11.13 *= /= %= += -= <<= >>= >>>= &= ^= |=ต่อไปนี้เป็นรายการครบถ้วนสมบูรณ์ของผู้ประกอบการที่ได้รับมอบหมายสารประกอบ:

ตามส่วนที่ 11.11 var c = a || bจะใส่aค่าลงในcถ้าToBoolean(a)เป็นจริงและจะใส่bค่าลงไปเป็นcอย่างอื่น เช่นนั้นเหตุผลหรือมักจะถูกใช้เป็นตัวดำเนินการรวมกันเช่น

function (options) {
    options = options || {};
}

a = a || bบ่อยพอรวมกันถูกใช้เพื่อระบุค่าเริ่มต้นสำหรับตัวแปรตามที่ได้แสดงไว้ด้านบน:

ดูเหมือนว่าผู้ประกอบการที่ได้รับมอบหมายสารประกอบจะเป็นประโยชน์จริงๆที่ช่วยให้การเขียนโค้ดข้างต้นในแฟชั่นสั้นและทำความสะอาด:||= a ||= bแต่ก็ไม่ได้มี (แม้ว่า*=, +=และผู้ประกอบการที่ได้รับมอบหมายสารประกอบอื่น ๆ )

คำถามคือทำไม


2
ฉันงงงวยอย่างไม่น่าเชื่อว่า% = โอเปอเรเตอร์ยังคงอยู่ ใครเป็นคนตัดสินใจว่าจำเป็นหรือไม่ ผู้ประกอบการเหล่านี้บางคนดูเหมือนว่าการตัดสินใจออกแบบภาษาจะไม่ดี
Jonathan Rich

2
@JonathanRich: ทำไมไม่มี% = หากคุณกำลังจะมีผู้ดำเนินการที่ได้รับมอบหมายเหล่านี้ไม่ช้าก็เร็วนักพัฒนาบางคน (เช่น penartur) จะสงสัยว่าทำไมตัวดำเนินการ "เท่ากัน" กว่าผู้อื่น
วินไคลน์

4
@JonathanRich Crypto ใช้โมดูลัสอย่างมีนัยสำคัญ Furthemore มีฉากที่ต้องการกับส่วนที่เหลือของเลขคณิตเพื่อผู้ประกอบการที่ได้รับมอบหมายเลขคณิต (ถ้าใครคาดหวัง+=, *=, -=, /=ทำไมจะไม่%=ทำงาน?)

4
@JonathanRich: ตัวดำเนินการมีประโยชน์เมื่อคุณมีบางสิ่งบางอย่างเป็นวงกลมและต้องการทำให้เป็นมาตรฐานเช่นangle %= 360หรือvertexIndex %= numberOfVertices(สำหรับรายการจุดยอดของรูปหลายเหลี่ยมปิด)
Sebastian Negraszus

คำตอบ:


12

เหตุผลหนึ่งที่เป็นไปได้คือตัวดำเนินการเชิงตรรกะ&&และ||มีพฤติกรรม "ลัดวงจร" ตัวถูกดำเนินการทางขวามือของ&&และ||ไม่ได้รับการประเมินเว้นแต่จำเป็น ด้วยเหตุผลนี้เองที่นักออกแบบภาษาตัดสินใจว่าความหมายของการแสดงออกเช่นa ||= f()นั้นไม่ชัดเจนนัก


2
ใช่. ตัวอย่างเช่นหลายคนเชื่อว่าa ||= bควรตีความได้ว่าa = a || bแต่จริง ๆ แล้วมันอาจจะเป็นa || a = b(เช่นในทับทิม ) พวกเขาอาจแตกต่างกันถ้าสุนัขมีผลข้างเคียง การเลือกอันใดอันหนึ่งอาจไม่ดีสำหรับผู้ใช้ในค่ายอื่น ฉันชอบa || a = bวิธีส่วนตัว(ทางรูบี) แต่ฉันไม่แน่ใจว่าทุกคนมีความสุขกับเรื่องนี้หรือไม่
Franklin Yu

8

คำตอบทั่วไปสำหรับคำถามทั้งหมดเกี่ยวกับ "ทำไมคุณลักษณะภาษานี้จึงไม่ได้นำไปใช้" คือทีมที่ออกแบบภาษาตัดสินใจว่าประโยชน์ไม่ได้มีค่าเกิน

ราคาสามารถมีได้หลายรูปแบบ ต้องใช้เวลาและความพยายามในการใช้คุณลักษณะภาษา แต่ยังมีค่าใช้จ่ายที่ซับซ้อนภายใน: คุณลักษณะนี้ทำให้ภาษาซับซ้อนหรือคลุมเครือมากขึ้นซึ่งไม่ได้สัดส่วนกับผลประโยชน์ที่อาจเกิดขึ้นหรือไม่

||=ผู้ประกอบการสมมุติทำอะไรบางอย่างที่แตกต่างจากผู้ประกอบการมอบหมายสารประกอบอื่น ๆ ในขณะที่โอเปอเรเตอร์อื่น ๆ มีลักษณะทางคณิตศาสตร์ล้วนๆ แต่อันนี้ต่างออกไป: มันแทนค่าหนึ่งสำหรับอีกอันหนึ่ง (ในบริบทที่คุณอธิบาย)

ด้วยความคลุมเครือนี้(ผู้ปฏิบัติงานทำหน้าที่สองอย่างที่แตกต่างกันขึ้นอยู่กับบริบท) จึงไม่ยากที่จะดูว่าทำไมจึงไม่รวมอยู่ในภาษา แม้ว่าคุณระบุว่าการเปลี่ยนแปลง

function (options) {
    options = options || {};
}

ถึง

function (options) {
    options ||= {};
}

การรวมกันเป็นโมฆะเป็นคุณสมบัติที่มีคุณค่าผลประโยชน์นั้นชัดเจนน้อยกว่าสำหรับฉัน หากการทดแทนค่าเกิดขึ้นดูเหมือนว่ามีเหตุผล (และชัดเจนขึ้น) ที่มีทั้งสองค่าที่ด้านขวาของเครื่องหมายเท่ากับ

C # ใช้เส้นทางที่แตกต่างและใช้โอเปอเรเตอร์เฉพาะสำหรับการรวมกันเป็นโมฆะ


1
เมื่ออ่านรหัสตัวอย่างแรกที่อ่านจะเป็นธรรมชาติมากขึ้น - "ตัวเลือกเท่ากับตัวเลือกหรือไม่มีอะไร" - เมื่อเปรียบเทียบกับตัวเลือกที่สอง - "ตัวเลือกหรือเท่ากับไม่มีอะไร" ฉันคิดว่านี่เป็นอีกเหตุผลหนึ่งที่ไม่รวมตัวดำเนินการ "หรือเท่ากับ"
Andy Hunt

การเปิดคำตอบของคุณอย่างยอดเยี่ยม และฉันคิดว่าจุดเริ่มต้นของคำตอบของคุณอยู่ในวิกิสำหรับแท็ก

3
@AndyBursh ตรรกะเดียวกันนี้สามารถนำไปใช้กับผู้ประกอบการกำหนดสารประกอบใด ๆ "X เท่ากับ X คูณ 2" อ่านอย่างเป็นธรรมชาติมากกว่าเมื่อเทียบกับ "X คูณเท่ากับ 2"
penartur

2
โปรดทราบว่าการพิมพ์foo = foo || barต้องให้คุณพิมพ์fooสองครั้ง นี่เป็นทั้งความยุ่งยากและมีแนวโน้มที่จะพิมพ์ผิดซ้ำ
Phrogz

1
ฉันคิดว่าคุณเข้าใจผิดความหมายของ "คณิตศาสตร์" บางทีคุณอาจเคยได้ยินเกี่ยวกับพีชคณิตแบบบูล ฉันยอมรับการบีบบังคับที่ไม่ใช้บูลีนเพื่อใช้||=เป็นโอเปอเรเตอร์การรวมตัวกันที่ไม่ได้ใช้งานง่ายและในความเป็นจริงแล้วดูเป็นป้านในรูปแบบรหัส สิ่งที่มันจะมีประโยชน์คือเมื่อคุณพยายามทำคณิตศาสตร์บูลีน function fulfill(inValue) { if(resolved || rejected) return false; /* Do stuff here */ return true; } resolved ||= fulfill(value)
joshperry

3

คุณพูดถูกที่||=เป็นโครงสร้างที่มีประโยชน์ มันมีอยู่ใน Perl

ในความเป็นจริง Perl ทำให้สิ่งเหล่านี้พร้อมใช้งาน:

**=    +=    *=    &=    <<=    &&=   -=    /=    
|=     >>=   ||=   .=    %=     ^=    //=   x=

บางสิ่งเหล่านี้ยอดเยี่ยม ( .=เพิ่มบางอย่างที่ส่วนท้ายของสตริง), อื่น ๆ น้อยดังนั้น ( &&=??? ฉันคิดว่าตัวแปรจะได้รับการตั้งค่าทางด้านขวาถ้าทั้งสองอย่างและตัวแปรนั้นเป็นจริง แต่ทำไมคุณถึงทำแบบนี้ ?)

สิ่งที่รวมอยู่ในภาษาเป็นคุณสมบัติของปรัชญาการออกแบบ


3
stackoverflow.com/questions/12589467/…สำหรับสิ่งที่&&=หมายถึง / ไม่
จ้า
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.