หลายภาษาเลือกเส้นทางในการกำหนดคำสั่งแทนนิพจน์รวมถึง Python:
foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg
และ Golang:
var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies
ภาษาอื่น ๆ ไม่มีการบ้าน แต่ค่อนข้างจะถูก จำกัด ขอบเขตเช่น OCaml:
let foo = 42 in
if foo = 42 then
print_string "hi"
อย่างไรก็ตามlet
เป็นการแสดงออกของตัวเอง
ข้อดีของการอนุญาตให้ทำงานคือเราสามารถตรวจสอบค่าส่งคืนของฟังก์ชั่นภายในเงื่อนไขได้โดยตรงเช่นในตัวอย่างของ Perl นี้:
if (my $result = some_computation()) {
say "We succeeded, and the result is $result";
}
else {
warn "Failed with $result";
}
Perl ยังกำหนดขอบเขตการประกาศเงื่อนไขเท่านั้นซึ่งทำให้มีประโยชน์มาก นอกจากนี้ยังจะเตือนถ้าคุณกำหนดภายในเงื่อนไขโดยไม่ต้องประกาศตัวแปรใหม่ที่นั่น - if ($foo = $bar)
จะเตือนif (my $foo = $bar)
จะไม่
การกำหนดในคำสั่งอื่นมักจะเพียงพอ แต่สามารถนำปัญหาการกำหนดขอบเขต:
my $result = some_computation()
if ($result) {
say "We succeeded, and the result is $result";
}
else {
warn "Failed with $result";
}
# $result is still visible here - eek!
Golang พึ่งพาค่าส่งคืนอย่างมากสำหรับการตรวจสอบข้อผิดพลาด ดังนั้นจึงอนุญาตให้เงื่อนไขที่จะใช้คำสั่งการเริ่มต้น:
if result, err := some_computation(); err != nil {
fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)
ภาษาอื่นใช้ระบบชนิดเพื่อไม่อนุญาตนิพจน์ที่ไม่ใช่บูลีนภายในเงื่อนไข:
int foo;
if (foo = bar()) // Java does not like this
แน่นอนว่าล้มเหลวเมื่อใช้ฟังก์ชันที่คืนค่าบูลีน
ขณะนี้เราได้เห็นกลไกต่าง ๆ เพื่อป้องกันการมอบหมายโดยไม่ได้ตั้งใจ:
- ไม่อนุญาตการมอบหมายเป็นนิพจน์
- ใช้การตรวจสอบประเภทคงที่
- การมอบหมายไม่มีอยู่จริงเรามีแค่
let
การผูกเท่านั้น
- อนุญาตให้เริ่มต้นคำสั่งไม่อนุญาตการมอบหมายเป็นอย่างอื่น
- ไม่อนุญาตการมอบหมายภายในเงื่อนไขโดยไม่มีการประกาศ
ฉันได้จัดอันดับพวกเขาตามลำดับจากน้อยไปมาก - การมอบหมายภายในนิพจน์อาจมีประโยชน์ (และเป็นเรื่องง่ายที่จะหลีกเลี่ยงปัญหาของ Python โดยมีไวยากรณ์การประกาศที่ชัดเจนและไวยากรณ์อาร์กิวเมนต์ที่มีชื่อต่างกัน) แต่มันก็โอเคที่จะไม่อนุญาตเนื่องจากมีตัวเลือกอื่น ๆ มากมายที่ให้ผลเหมือนกัน
รหัสที่ไม่มีข้อผิดพลาดสำคัญกว่ารหัสตัวอักษร