Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

แพ็กเกจ (Packages), เครต (Crates) และโมดูล (Modules)

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

โปรแกรมที่เราเขียนกันมาจนถึงตอนนี้ล้วนเก็บอยู่ในโมดูลเดียวในไฟล์เดียว แต่ทว่าเมื่อโปรเจกต์เติบโตขึ้น คุณควรจัดระเบียบโค้ดโดยแบ่งย่อยออกเป็นหลายโมดูล และแยกเป็นหลายไฟล์ตามลำดับ แพ็กเกจ (package) หนึ่งสามารถประกอบด้วยเครตฐานสอง (binary crates) หลายเครต และมีเครตห้องสมุด (library crate) ได้หนึ่งเครตเป็นทางเลือก เมื่อแพ็กเกจขยายตัวขึ้น คุณสามารถดึงบางส่วนออกไปสร้างเป็นเครตแยกต่างหากซึ่งจะกลายเป็นทรัพยากรภายนอก (external dependencies) ที่ต้องนำเข้ามาใช้งาน ในบทนี้จะครอบคลุมถึงเทคนิคเหล่านี้ทั้งหมด สำหรับโปรเจกต์ขนาดใหญ่มากที่ประกอบด้วยกลุ่มแพ็กเกจที่มีความเกี่ยวข้องกันและพัฒนาไปด้วยกัน ทาง Cargo ก็จะมีระบบพื้นที่ทำงาน (workspaces) ให้ใช้งาน ซึ่งเราจะศึกษาเพิ่มเติมในส่วน“Cargo Workspaces” ในบทที่ 14

นอกจากนี้เรายังจะอภิปรายเกี่ยวกับการห่อหุ้มรายละเอียดการทำงานภายใน (encapsulating implementation details) ซึ่งช่วยให้คุณนำโค้ดกลับมาใช้ใหม่ได้ในระดับที่สูงขึ้น กล่าวคือ เมื่อคุณสร้างการทำงานขึ้นมาแล้ว โค้ดส่วนอื่น ๆ จะสามารถเรียกใช้งานโค้ดของคุณผ่านทางอินเตอร์เฟสสาธารณะ (public interface) ได้โดยไม่จำเป็นต้องรับรู้เลยว่ารายละเอียดภายในทำงานอย่างไร วิธีการเขียนโค้ดของคุณจะเป็นตัวกำหนดว่าส่วนใดที่เป็นสาธารณะ (public) ที่ให้โค้ดอื่นสามารถนำไปเรียกใช้ได้ และส่วนใดที่เป็นรายละเอียดภายในส่วนตัว (private implementation details) ที่คุณสงวนสิทธิ์ที่จะปรับเปลี่ยนแก้ไขได้ในอนาคต ซึ่งนี่เป็นอีกหนึ่งวิธีในการช่วยจำกัดปริมาณรายละเอียดข้อมูลที่คุณจำเป็นต้องจดจำไว้ในสมอง

แนวคิดที่มีความเกี่ยวข้องใกล้ชิดกันคือ ขอบเขตการทำงาน (scope): บริบทการเขียนโค้ดแบบซ้อนระดับชั้นจะมีชุดรายชื่อต่าง ๆ ที่ถูกประกาศว่าอยู่ในขอบเขต (“in scope”) ในขณะที่อ่าน เขียน และคอมไพล์โค้ด ทั้งโปรแกรมเมอร์และคอมไพเลอร์จำเป็นต้องรู้ว่าชื่อเฉพาะ ณ จุดหนึ่ง ๆ ในโค้ดนั้น หมายถึงตัวแปร, ฟังก์ชัน, struct, enum, โมดูล, ค่าคงที่ (constant) หรือไอเท็มอื่น ๆ และไอเท็มนั้นหมายความว่าอย่างไร คุณสามารถสร้างขอบเขตใหม่และปรับแต่งรายชื่อที่อยู่ภายในหรือภายนอกขอบเขตได้ ทั้งนี้คุณไม่สามารถมีไอเท็มสองชิ้นที่มีชื่อเดียวกันในขอบเขตการทำงานเดียวกันได้ แต่อย่างไรก็ตาม จะมีเครื่องมือต่าง ๆ พร้อมใช้งานเพื่อช่วยแก้ไขปัญหาความขัดแย้งของชื่อที่ซ้ำซ้อนกัน

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

  • Packages (แพ็กเกจ): ฟีเจอร์ของ Cargo ที่ช่วยให้คุณสร้าง ทดสอบ และแบ่งปันเครตต่าง ๆ ได้
  • Crates (เครต): โครงสร้างแบบต้นไม้ของโมดูลต่าง ๆ ที่สร้างขึ้นมาเป็นห้องสมุด (library) หรือไฟล์โปรแกรมประมวลผล (executable)
  • Modules (โมดูล) และ use: ช่วยให้คุณควบคุมการจัดระเบียบ, ขอบเขต และความเป็นส่วนตัวของเส้นทางข้อมูล (paths)
  • Paths (เส้นทาง): วิธีในการตั้งชื่อระบุไอเท็ม เช่น struct, ฟังก์ชัน หรือโมดูล

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