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
ที่สามารถเขียนได้ในแง่ของ