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 and Crates)

ส่วนแรกสุดของระบบโมดูลที่เราจะมาทำความรู้จักกันคือ แพ็กเกจ (packages) และ เครต (crates)

เครต (crate) คือปริมาณโค้ดที่มีขนาดเล็กที่สุดที่คอมไพเลอร์ของ Rust จะพิจารณาในคราวเดียว แม้ว่าคุณจะรันคำสั่ง rustc โดยตรงไม่ใช่ cargo และส่งไฟล์ซอร์สโค้ดเพียงไฟล์เดียวเข้าไป (เหมือนที่เราทำในส่วน“พื้นฐานโปรแกรม Rust” ในบทที่ 1) คอมไพเลอร์ก็ยังจะพิจารณาว่าไฟล์ดังกล่าวเป็นเครตหนึ่ง เครตสามารถประกอบไปด้วยโมดูลต่าง ๆ และโมดูลเหล่านั้นอาจถูกกำหนดแยกไว้ในไฟล์อื่น ๆ ที่จะถูกคอมไพล์ร่วมกันกับเครตนั้นได้ ดังที่เราจะได้ศึกษาในส่วนถัด ๆ ไป

เครตสามารถแบ่งรูปแบบออกได้เป็นสองประเภทหลัก ๆ คือ เครตฐานสอง (binary crate) หรือ เครตห้องสมุด (library crate)

เครตฐานสอง (binary crates) คือโปรแกรมที่คุณสามารถคอมไพล์เป็นไฟล์ประมวลผล (executable) ที่รันใช้งานได้จริง เช่น โปรแกรมแบบบรรทัดคำสั่ง (command line) หรือระบบเซิร์ฟเวอร์ โดยแต่ละเครตจำเป็นต้องมีฟังก์ชันที่ชื่อว่า main เพื่อกำหนดสิ่งที่เกิดขึ้นเมื่อรันไฟล์ประมวลผลนั้น ซึ่งเครตทั้งหมดที่เราสร้างขึ้นมาจนถึงตอนนี้ล้วนเป็นเครตฐานสองทั้งสิ้น

เครตห้องสมุด (library crates) จะไม่มีฟังก์ชัน main และจะไม่ถูกคอมไพล์ออกมาเป็นไฟล์ประมวลผลที่รันได้โดยตรง แต่ทว่าพวกมันจะถูกกำหนดฟังก์ชันการทำงานเพื่อนำไปแบ่งปันใช้งานร่วมกับหลาย ๆ โปรเจกต์ ตัวอย่างเช่น เครต rand ที่เราเลือกใช้ในบทที่ 2 ซึ่งให้บริการความสามารถในการสุ่มตัวเลข โดยส่วนใหญ่แล้วเมื่อกลุ่มคนที่เขียนภาษา Rust (Rustaceans) พูดถึงคำว่า “เครต (crate)” มักจะสื่อความหมายถึงเครตห้องสมุด และนิยมใช้คำว่า “เครต” สลับสับเปลี่ยนไปมาแทนแนวคิดทั่วไปในการเขียนโปรแกรมอย่างคำว่า “ไลบรารี (library)”

รากเครต (crate root) คือไฟล์ซอร์สโค้ดเริ่มต้นที่คอมไพเลอร์ของ Rust จะเริ่มทำการตรวจสอบเป็นจุดแรกสุด และถือเป็นโมดูลรากของเครตของคุณ (เราจะอธิบายเกี่ยวกับโมดูลแบบเจาะลึกในส่วน“ควบคุมขอบเขตและความเป็นส่วนตัวด้วยโมดูล”)

แพ็กเกจ (package) คือกลุ่มของเครตตั้งแต่หนึ่งเครตขึ้นไปที่มารวมตัวกันเพื่อมอบคุณสมบัติการทำงานชุดหนึ่ง แพ็กเกจจะมีไฟล์ Cargo.toml บรรจุอยู่ซึ่งระบุข้อมูลวิธีการสร้างเครตเหล่านั้น อันที่จริงแล้วระบบ Cargo ก็เป็นแพ็กเกจหนึ่งที่ประกอบไปด้วยเครตฐานสองสำหรับเครื่องมือบรรทัดคำสั่งที่คุณใช้สร้างและคอมไพล์โค้ดของคุณ และแพ็กเกจ Cargo ก็ยังมีเครตห้องสมุดที่เครตฐานสองจำเป็นต้องใช้งานเชื่อมโยงอยู่ด้วย โดยโปรเจกต์อื่น ๆ ก็สามารถเลือกนำเอาเครตห้องสมุดของ Cargo นี้ไปเชื่อมโยงใช้งานตรรกะแบบเดียวกับที่เครื่องมือบรรทัดคำสั่ง Cargo ใช้งานได้เช่นกัน

แพ็กเกจสามารถจัดเก็บเครตฐานสองได้มากเท่าที่คุณต้องการ แต่ทว่าจะมีเครตห้องสมุดบรรจุอยู่ได้มากที่สุดเพียงหนึ่งเครตเท่านั้น และแพ็กเกจจำเป็นต้องมีเครตบรรจุอยู่อย่างน้อยหนึ่งเครต ไม่ว่าจะเป็นเครตห้องสมุดหรือเครตฐานสองก็ตาม

เรามาดูรายละเอียดขั้นตอนที่เกิดขึ้นเมื่อเราสั่งสร้างแพ็กเกจกัน เริ่มแรกเราจะพิมพ์คำสั่ง cargo new my-project:

$ cargo new my-project
     Created binary (application) `my-project` package
$ ls my-project
Cargo.toml
src
$ ls my-project/src
main.rs

หลังจากที่เราสั่งรัน cargo new my-project แล้ว เราจะใช้คำสั่ง ls เพื่อตรวจสอบสิ่งต่าง ๆ ที่ระบบ Cargo สรรสร้างขึ้นมา โดยภายในไดเรกทอรี my-project จะมีไฟล์ Cargo.toml ปรากฏอยู่ ซึ่งแสดงความจำนงเป็นแพ็กเกจ นอกจากนี้ยังมีไดเรกทอรี src ที่เก็บไฟล์ main.rs อยู่ด้วย เมื่อลองเปิดไฟล์ Cargo.toml ในโปรแกรมแก้ไขข้อความของคุณ จะสังเกตพบว่าไม่มีการเขียนระบุชื่อของ src/main.rs อยู่ในไฟล์เลย เนื่องจากระบบ Cargo ทำงานตามข้อตกลงร่วมกัน (convention) ว่าไฟล์ src/main.rs จะทำหน้าที่เป็นรากเครต (crate root) ของเครตฐานสองที่มีชื่อเดียวกับชื่อแพ็กเกจ ในทำนองเดียวกัน Cargo ก็จะรู้ทันทีว่าหากไดเรกทอรีของแพ็กเกจมีไฟล์ src/lib.rs บรรจุอยู่ ก็หมายความว่าแพ็กเกจดังกล่าวมีเครตห้องสมุดที่ตั้งชื่อเดียวกับชื่อแพ็กเกจ และให้ไฟล์ src/lib.rs ทำหน้าที่เป็นรากเครตของมัน โดย Cargo จะส่งผ่านไฟล์รากเครตเหล่านี้ต่อไปยัง rustc เพื่อประมวลผลสร้างเป็นห้องสมุดหรือไฟล์โปรแกรมประมวลผลจริง

ในตัวอย่างนี้ เรามีแพ็กเกจที่บรรจุเพียงไฟล์ src/main.rs เท่านั้น ซึ่งหมายความว่ามันมีเพียงเครตฐานสองชื่อ my-project เพียงเครตเดียว แต่หากในแพ็กเกจมีทั้งไฟล์ src/main.rs และ src/lib.rs ก็หมายความว่ามันมีเครตสองตัวด้วยกัน คือเครตฐานสองและเครตห้องสมุด ซึ่งทั้งคู่จะใช้ชื่อเดียวกับแพ็กเกจ นอกจากนี้แพ็กเกจสามารถบรรจุเครตฐานสองได้หลายตัวโดยการนำไฟล์เหล่านั้นไปวางไว้ในไดเรกทอรี src/bin ซึ่งแต่ละไฟล์ในนั้นจะถูกประมวลผลแยกเป็นเครตฐานสองของตนเอง