การแปลงโดยนัยนั้นค่อนข้างเป็นไปได้ที่จะทำ สถานการณ์ที่คุณมีปัญหาคือเมื่อคุณไม่รู้ว่าควรจะทำงานอย่างไร
ตัวอย่างนี้สามารถเห็นได้ใน Javascript ที่+
ผู้ประกอบการทำงานในรูปแบบที่แตกต่างกันในเวลาที่ต่างกัน
>>> 4 + 3
7
>>> "4" + 3
43
>>> 4 + "3"
43
หากหนึ่งในอาร์กิวเมนต์เป็นสตริงตัว+
ดำเนินการคือการต่อสายอักขระมิฉะนั้นจะเป็นการเพิ่ม
หากคุณได้รับการโต้แย้งและไม่ทราบว่ามันเป็นสตริงหรือจำนวนเต็มและต้องการเพิ่มเข้าไปด้วยมันอาจเป็นเรื่องยุ่งเล็กน้อย
อีกวิธีในการจัดการกับสิ่งนี้คือจากมรดกพื้นฐาน (ที่ perl ดังนี้ - ดูการเขียนโปรแกรมเป็นเรื่องยาก Let's Scripting ... )
ในขั้นพื้นฐานlen
ฟังก์ชั่นจะทำให้เกิดความรู้สึกถูกเรียกบน String เท่านั้น (เอกสารสำหรับvisual Basic : "นิพจน์สตริงหรือชื่อตัวแปรใด ๆ ที่ถูกต้องถ้า Expression เป็นประเภทวัตถุ Object ฟังก์ชั่น Len จะส่งกลับขนาดตามที่มันจะถูกเขียนลงในไฟล์ ฟังก์ชัน FilePut ")
Perl เป็นไปตามแนวคิดของบริบทนี้ ความสับสนที่มีอยู่ใน JavaScript กับการแปลงโดยนัยของชนิดสำหรับ+
ผู้ประกอบการเป็นบางครั้งและบางครั้งนอกจากเรียงต่อกันไม่ได้เกิดขึ้นใน Perl เพราะ+
เป็นเสมอนอกจากนี้และ.
เป็นเสมอเรียงต่อกัน
หากมีการใช้บางสิ่งในบริบทสเกลาร์มันเป็นสเกลาร์ (เช่นใช้รายการเป็นสเกลาร์รายการจะทำงานเหมือนเป็นตัวเลขที่สอดคล้องกับความยาว) หากคุณใช้ตัวดำเนินการสตริง ( eq
สำหรับการทดสอบความเท่าเทียมกันcmp
สำหรับการเปรียบเทียบสตริง) สเกลาร์ถูกใช้ราวกับว่ามันเป็นสตริง ในทำนองเดียวกันหากมีการใช้บางสิ่งในบริบททางคณิตศาสตร์ ( ==
สำหรับการทดสอบความเท่าเทียมกันและ<=>
การเปรียบเทียบเชิงตัวเลข) สเกลาร์จะถูกใช้ราวกับว่าเป็นตัวเลข
กฎพื้นฐานสำหรับการเขียนโปรแกรมทั้งหมดคือ "ทำในสิ่งที่ทำให้คนประหลาดใจน้อยที่สุด" นี่ไม่ได้หมายความว่าไม่มีความประหลาดใจอยู่ในนั้น แต่ความพยายามคือการทำให้คน ๆ นั้นประหลาดใจน้อยที่สุด
เมื่อไปถึงลูกพี่ลูกน้องอย่างใกล้ชิดของ perl - php มีสถานการณ์ที่ผู้ปฏิบัติงานสามารถทำอะไรบางอย่างในบริบทสตริงหรือตัวเลขและพฤติกรรมสามารถสร้างความประหลาดใจให้กับผู้คน ++
ประกอบเป็นตัวอย่างหนึ่งเช่น ในตัวเลขมันทำงานตรงตามที่คาดไว้ เมื่อดำเนินการกับสตริงเช่น"aa"
จะเพิ่มสตริง ( $foo = "aa"; $foo++; echo $foo;
พิมพ์ab
) นอกจากนี้ยังจะเกลือกกลิ้งเพื่อที่ว่าเมื่อเพิ่มขึ้นจะกลายเป็นaz
ba
สิ่งนี้ไม่น่าประหลาดใจโดยเฉพาะอย่างยิ่ง
$foo = "3d8";
echo "$foo\n";
$foo++;
echo "$foo\n";
$foo++;
echo "$foo\n";
$foo++;
echo "$foo\n";
( ideone )
สิ่งนี้พิมพ์ออกมา:
3d8
3d9
3e0
4
ยินดีต้อนรับสู่อันตรายของการแปลงและตัวดำเนินการโดยปริยายซึ่งทำหน้าที่แตกต่างกันในสายอักขระเดียวกัน (Perl จัดการโค้ดบล็อกนั้นแตกต่างกันเล็กน้อย - ตัดสินใจว่า"3d8"
เมื่อตัว++
ดำเนินการถูกนำไปใช้เป็นค่าตัวเลขตั้งแต่เริ่มต้นและไป4
ทันที ( ideone ) - พฤติกรรมนี้อธิบายได้ดีในperlop: การเพิ่มขึ้นอัตโนมัติและการลดลงอัตโนมัติ )
ทีนี้ทำไมภาษาหนึ่งถึงทำสิ่งหนึ่งทางหนึ่งและอีกภาษาหนึ่งทำให้อีกความคิดการออกแบบของนักออกแบบ ปรัชญาของ Perl คือมีมากกว่าหนึ่งวิธีที่จะทำ - และฉันสามารถคิดถึงวิธีการบางอย่างในการดำเนินการบางอย่าง ในอีกทางหนึ่ง Python มีปรัชญาที่อธิบายไว้ในPEP 20 - The Zen of Pythonซึ่งกล่าวถึง (เหนือสิ่งอื่นใด): "ควรมีอย่างใดอย่างหนึ่ง - และดีกว่าเพียงวิธีเดียวเท่านั้น - ชัดเจนวิธีที่จะทำ"
ความแตกต่างของการออกแบบเหล่านี้นำไปสู่ภาษาที่แตกต่างกัน มีวิธีหนึ่งในการรับความยาวของตัวเลขใน Python การแปลงโดยปริยายนั้นขัดกับปรัชญานี้
การอ่านที่เกี่ยวข้อง: ทำไม Ruby จึงไม่มีการแปลง Fixnum ให้เป็น String โดยนัย?
perl -e 'print length(100);'
ภาพที่ 3