TL; DR: whenเกี่ยวกับผลข้างเคียงandมีไว้สำหรับนิพจน์บูลีนบริสุทธิ์
ตามที่คุณสังเกตเห็นandและwhenแตกต่างในรูปแบบไวยากรณ์ แต่จะเทียบเท่ากันทั้งหมด
ความแตกต่างของวากยสัมพันธ์เป็นสิ่งสำคัญมากแม้ว่า: whenล้อมprognรอบทั้งหมด แต่รูปแบบการโต้แย้งครั้งแรก prognมันเป็นคุณสมบัติที่จำเป็นอย่างยิ่ง: มันประเมินผลทั้งหมด แต่รูปแบบสุดท้ายของร่างกายสำหรับผลข้างเคียงของพวกเขาเท่านั้นโดยละทิ้งสิ่งที่พวกเขากลับมา
เช่นwhenนี้เป็นรูปแบบที่จำเป็นเช่นกัน: มันมีจุดประสงค์หลักคือการห่อรูปแบบที่มีผลข้างเคียงเพราะเฉพาะค่าของรูปแบบสุดท้ายเท่านั้นที่สำคัญสำหรับร่างกาย
andในทางกลับกันเป็นฟังก์ชั่นที่บริสุทธิ์ซึ่งมีจุดประสงค์หลักคือการดูค่าที่ส่งคืนของรูปแบบอาร์กิวเมนต์ที่กำหนด: หากคุณไม่ได้prognล้อมอาร์กิวเมนต์ใด ๆไว้อย่างชัดเจนค่าของรูปแบบอาร์กิวเมนต์ทั้งหมดจะมีความสำคัญและไม่มีค่าใดถูกเพิกเฉย .
ดังนั้นความแตกต่างที่แท้จริงระหว่างandและwhenเป็นโวหาร: คุณใช้andสำหรับการแสดงออกทางบูลีนที่บริสุทธิ์และwhenเพื่อป้องกันรอบ ๆ แบบฟอร์มที่มีผลข้างเคียง
ดังนั้นสิ่งเหล่านี้จึงเป็นรูปแบบที่ไม่ดี:
;; `when' used for a pure boolean expression
(let ((use-buffer (when (buffer-live-p buffer)
(file-exists-p (buffer-file-name buffer)))))
...)
;; `and' used as guard around a side-effecting form
(and (buffer-file-name buffer) (write-region nil nil (buffer-file-name buffer)))
และสิ่งเหล่านี้ดี
(let ((use-buffer (and (buffer-live-p buffer)
(file-exists-p (buffer-file-name buffer)))))
...)
(when (buffer-file-name buffer)
(write-region nil nil (buffer-file-name buffer)))
ฉันรู้ว่าบางคนไม่เห็นด้วยกับเรื่องนี้และใช้andเพื่อป้องกันผลข้างเคียงอย่างมีความสุขแต่ฉันคิดว่านี่เป็นสไตล์ที่ไม่ดีจริงๆ เรามีรูปแบบที่แตกต่างกันเหล่านี้สำหรับเหตุผล: ไวยากรณ์ที่สำคัญ หากไม่เป็นเช่นนั้นเราทุกคนจะเคยใช้ifซึ่งเป็นรูปแบบเงื่อนไขเดียวที่คุณต้องการใน Emacs Lisp ความหมาย ทุกรูปแบบบูลีนและเงื่อนไขอื่น ๆ ifที่สามารถเขียนได้ในแง่ของ