Hello, Cargo!

Cargo คือเครื่องมือจัดการแพ็กเก็จและระบบการบิ๊ลด์ของ Rust ซึ่ง Rustaceans ส่วนใหญ่ใช้เครื่องมือนี้เพื่อจัดการโปรเจกต์ Rust เนื่องจาก Cargo สามารถจัดการงานต่าง ๆ มากมายให้กับคุณได้ เช่น การบิ๊ลด์โค้ดของคุณ การดาวน์โหลดไลบรารีที่โค้ดของคุณต้องการ และทำการบิ๊ลด์ไลบรารีเหล่านั้น (เราเรียกไลบรารีที่โค้ดของคุณต้องการว่า dependencies)

โปรแกรมที่ง่ายที่สุดที่เราเคยเขียนมาแล้วก่อนหน้านี้ ไม่ได้ใช้ dependencies ใดเลย หากเราสร้างโปรเจกต์ “Hello, world!” ด้วย Cargo นั้น Cargo จะใช้บางส่วนของมันในการบิ๊ลด์โค้ดของคุณ และเมื่อคุณเขียนโปรแกรม Rust ที่ซับซ้อนมากขึ้น คุณอาจจำเป็นต้องเพิ่ม dependencies หากคุณสร้างโปรเจกต์โดยใช้ Cargo การเพิ่ม dependencies จะเป็นเรื่องที่ง่ายมาก

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

$ cargo --version

หากคุณเห็นหมายเลขเวอร์ชั่น แสดงว่าคุณได้ติดตั้ง Cargo แล้ว แต่หากคุณเห็นข้อความแจ้งข้อผิดพลาด เช่น command not found โปรดดูเอกสารประกอบวิธีการติดตั้งของคุณ เพื่อกำหนดวิธีการติดตั้ง Cargo โดยแยกกัน

การสร้างโปรเจกต์ด้วย Cargo

มาสร้างโปรเจกต์ใหม่โดยใช้ Cargo กัน และดูว่ามันแตกต่างจากโปรเจกต์ “Hello, world!” อันเดิมอย่างไร กลับไปที่โฟลเดอร์ projects ของคุณ (หรือโฟลเดอร์ใดก็ตามที่คุณใช้เก็บโค้ด) จากนั้น ไม่ว่าจะเป็นระบบปฏิบัติการใด ให้รันคำสั่งต่อไปนี้:

$ cargo new hello_cargo
$ cd hello_cargo

คำสั่งแรกจะสร้างโฟลเดอร์และโปรเจกต์ใหม่ที่มีชื่อว่า hello_cargo ซึ่งเราได้ตั้งชื่อโปรเจกต์ของเราว่า hello_cargo และ Cargo จะสร้างไฟล์ในโฟลเดอร์ที่มีชื่อเดียวกัน

ไปที่โฟลเดอร์ hello_cargo และแสดงรายการไฟล์ คุณจะพบว่า Cargo นั้นได้สร้างสองไฟล์และหนึ่งโฟลเดอร์ให้เรา โดยมีไฟล์ Cargo.toml โฟลเดอร์ src และไฟล์ main.rs อยู่ภายใน

นอกจากนั้นยังได้เริ่มต้นพื้นที่เก็บข้อมูล Git ใหม่ พร้อมกับไฟล์ .gitignore แต่ไฟล์ Git จะไม่ถูกสร้าง หากคุณรัน cargo new ภายในพื้นที่ที่มี Git อยู่แล้ว คุณสามารถเขียนทับ Git ที่มีอยู่เดิมโดยใช้ cargo new --vcs=git

หมายเหตุ: Git เป็นระบบการควบคุมเวอร์ชั่นทัวไป คุณสามารถเปลี่ยน cargo new เพื่อใช้งานระบบการควบคุมเวอร์ชั่นในรูปแบบอื่น หรือไม่ใช้เลย โดยทำการระบุ --vsc รันคำสั่ง cargo new --help เพื่อดูตัวเลือกที่เกี่ยวข้อง

เปิดไฟล์ Cargo.toml ในโปรแกรมแก้ไขข้อความที่คุณเลือก มันควรมีหน้าตาคล้ายกับโค้ดในรายการที่ 1-2

[package]
name = "hello_cargo"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]

ไฟล์นี้อยู่ในรูปแบบ TOML (Tom’s Obvious, Minimal Language) ซึ่งเป็นรูปแบบการกำหนดค่าของ Cargo

ในบรรทัดแรก [package] คือหัวข้อที่ระบุว่าคำสั่งที่ตามมานี้จะเป็นการกำหนดค่าแพ็กเก็จ เมือคุณเพิ่มข้อมูลลงในไฟล์นี้ คุณต้องเพิ่มส่วนอื่น ๆ ด้วย

สามบรรทัดถัดมาจะกำหนดข้อมูลที่ Cargo จำเป็นต้องใช้เพื่อคอมไพล์โปรแกรมของคุณ ได้แก่ ชื่อ เวอร์ชั่น และรุ่นของ Rust ที่ใช้ เราจะกล่าวถึง รุ่น ใน ภาคผนวก E

ในบรรทัดสุดท้าย [dependencies] คือจุดเริ่มต้นที่ให้คุณแสดงรายการใด ๆ ของ dependencies ที่โปรเจกต์ของคุณต้องการ ใน Rust แพ็กเก็จของโค้ดจะถูกเรียกว่า crates ในโปรเจกต์นี้เราไม่จำเป็นต้องใช้ crates อื่น แต่ในโปรเจกต์แรกของบทที่ 2 เราจะได้ใช้มัน ดังนั้นในตอนนี้ให้ใช้ไปทั้งแบบนี้ก่อน

ตอนนี้ให้เปิดไฟล์ src/main.rs และตรวจดู:

Filename: src/main.rs

fn main() {
    println!("Hello, world!");
}

Cargo ได้สร้างโปรแกรม “Hello, world!” ให้คุณ เช่นเดียวกับที่เราได้เขียนไปในรายการที่ 1-1! จนถึงตอนนี้ ความแตกต่างระหว่างโปรเจกต์ของเราและโปรเจกต์ที่ Cargo ได้สร้าง คือ Cargo วางโค้ดไว้ในโฟลเดอร์ src และเรามีไฟล์กำหนดค่าชื่อ Cargo.toml ในโฟลเดอร์บนสุด

Cargo คาดหวังว่าไฟล์โค้ดของคุณจะอยู่ในโฟลเดอร์ src ส่วนโฟลเดอร์บนสุดของโปรเจกต์มีไว้สำหรับไฟล์ README, ข้อมูลลิขสิทธิ์, ไฟล์กำหนดค่า, และอื่น ๆ ที่ไม่เกี่ยวข้องกับโค้ดของคุณ การใช้ Cargo จะช่วยคุณจัดระเบียบโปรเจกต์ของคุณ ที่นี่มีพื้นที่สำหรับทุกสิ่ง และทุกสิ่งก็อยู่ในพื้นที่ของมัน

หากคุณเริ่มโปรเจกต์โดยไม่ใช้ Cargo ดั่งที่เราทำในโปรเจกต์ “Hello, world!” คุณสามารถแปลงเป็นโปรเจกต์ที่ใช้ Cargo ได้ โดยทำการย้ายโค้ดของโปรเจกต์คุณไปไว้ในโฟลเดอร์ src และสร้างไฟล์ Cargo.toml ที่เหมาะสม หนึ่งในวิธีที่ง่ายที่จะได้ไฟล์ Cargo.toml มาก็คือ รันคำสั่ง Cargo init ซึ่งจะทำการสร้างไฟล์ Cargo.toml ให้คุณโดยอัตโนมัติ

การคอมไพล์และการรันโปรเจกต์ Cargo

ตอนนี้เรามาดูข้อแตกต่างเมื่อเราคอมไพล์และรันโปรแกรม “Hello, world!” ด้วย Cargo กัน! จากโฟลเดอร์ hello_cargo ของคุณ ให้คอมไพล์โดยใช้คำสั่งต่อไปนี้:

$ cargo build
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 2.85 secs

คำสั่งนี้จะสร้างไฟล์สำหรับรันไว้ใน target/debug/hello_cargo (หรือ target\debug\hello_cargo.exe บน Windows) แทนที่จะอยู่ในโฟลเดอร์ปัจจุบันที่คุณอยู่ เนื่องจากค่าเริ่มต้นของการคอมไพล์คือโหมดดีบัก Cargo จึงสร้างไฟล์ไบนารีไว้ในโฟลเดอร์ที่ชื่อ debug โดยคุณสามารถรันไฟล์ดังกล่าวโดยใช้คำสั่งต่อไปนี้:

$ ./target/debug/hello_cargo # หรือ .\target\debug\hello_cargo.exe สำหรับ Windows
Hello, world!

หากทุกอย่างเป็นไปได้ด้วยดี ข้อความ Hello, world! ควรปรากฏบนเทอร์มินัล การรันคำสั่ง cargo build ในครั้งแรกยังทำให้ Cargo สร้างไฟล์ใหม่ที่ระดับบนสุดชื่อว่า Cargo.lock ซึ่งไฟล์นี้จะทำหน้าที่ติดตามเวอร์ชั่นที่แน่นอนของ dependencies ในโปรเจกต์ของคุณ เนื่องจากโปรเจกต์นี้ไม่มี dependencies ใด ๆ ทำให้ไฟล์นี้มีขนาดเล็ก คุณไม่จำเป็นต้องแก้ไขไฟล์นี้ด้วยตนเอง Cargo จะทำการแก้ไขจัดการไฟล์นี้ให้คุณเอง

เราเพิ่งคอมไพล์โปรเจกต์นี้ด้วยคำสั่ง cargo build และรันด้วยคำสั่ง ./target/debug/hello_cargo แต่เราสามารถใช้ cargo run เพื่อคอมไพล์โค้ดและรันโปรแกรมได้ในคำสั่งเดียว ดังนี้:

$ cargo run
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `target/debug/hello_cargo`
Hello, world!

การใช้ cargo run นั้นสะดวกกว่าการที่ต้องมาจำว่า ต้องรันคำสั่ง cargo build และพิมพ์คำสั่งยาวเหยียดเพียงเพื่อรันไฟล์ไบนารี ดังนั้นนักพัฒนาส่วนใหญ่จึงใช้ cargo run

สังเกตว่าครั้งนี้เราไม่เห็นผลลัพธ์ที่ระบุว่า Cargo กำลังคอมไพล์ hello_cargo เนื่องจาก Cargo พบว่าไม่มีไฟล์ใดเปลี่ยนแปลง ดังนั้นจึงไม่จำเป็นต้องคอมไพล์ใหม่ซ้ำอีกครั้ง เพียงแค่รันไฟล์ไบนารีก็เพียงพอ และหากคุณมีการแก้ไขโค้ดของคุณ Cargo จะทำการคอมไพล์โปรเจกต์ใหม่อีกครั้งก่อนที่จะทำการรัน และคุณจะเห็นผลลัพธ์ดังต่อไปนี้

$ cargo run
   Compiling hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.33 secs
     Running `target/debug/hello_cargo`
Hello, world!

Cargo ยังจัดเตรียมคำสั่งที่ชื่อว่า cargo check ซึ่งคำสั่งนี้จะทำการตรวจสอบโค้ดของคุณอย่างรวดเร็ว เพื่อให้แน่ใจว่ามันจะสามารถคอมไพล์ได้ โดยที่ยังไม่ทำการสร้างไฟล์ไบนารี

$ cargo check
   Checking hello_cargo v0.1.0 (file:///projects/hello_cargo)
    Finished dev [unoptimized + debuginfo] target(s) in 0.32 secs

ทำไมคุณไม่จำเป็นต้องใช้ไฟล์ไบนารี บ่อยครั้งที่ cargo check นั้นเร็วกว่า cargo build มาก เนื่องจากมันจะข้ามขั้นตอนการสร้างไฟล์ไบนารี หากคุณต้องตรวจสอบโค้ดของคุณในระหว่างเขียนโค้ด การใช้ cargo check จะช่วยให้คุณรู้ได้เร็วขึ้นว่าโปรเจกต์ของคุณยังสมารถคอมไพล์ได้หรือไม่ ด้วยเหตุนี้ ชาว Rustaceans จำนวนมากจึงใช้คำสั่ง cargo check เป็นระยะ ๆ ในขณะที่พวกเขากำลังเขียนโปรแกรม เพื่อให้แน่ใจว่ามันจะสามารถคอมไพล์ได้ จากนั้นพวกเขาจะรันคำสั่ง cargo build เมื่อพวกเขาพร้อมที่จะใช้งานไฟล์ไบนารี

มาสรุปสิ่งที่ได้เรียนรู้เกี่ยวกับ Cargo กัน:

  • เราสามารถโปรเจกต์โดยใช้ cargo new
  • เราสามารถคอมไพล์โปรเจกต์โดยใช้ cargo build
  • เราสามารถคอมไพล์และรันโปรเจกต์ในขั้นตอนเดียว โดยใช้ cargo run
  • เราสามารถตรวจสอบโปรเจกต์โดยไม่จำเป็นต้องสร้างไฟล์ไบนารี เพื่อทำการตรวจสอบข้อผิดพลาด โดยใช้ cargo check
  • แทนที่จะเก็บผลลัพธ์จากการคอมไพล์ไว้ในโฟลเดอร์เดียวกันกับโค้ดของคุณ Cargo เก็บมันไว้ที่โฟลเดอร์ target/debug แทน

ข้อได้เปรียบเพิ่มเติมเกี่ยวกับการใช้ Cargo คือ คำสั่งนั้นจะเหมือนเดิมไม่ว่าคุณจะใช้ระบบปฏิบัติการใดก็ตาม ดังนั้น ณ จุดนี้ เราจะไม่มีคำแนะนำที่จำเพาะกับ Linux และ MacOS หรือ Windows อีกต่อไป

การคอมไพล์เพื่อเผยแพร่

เมื่อโปรเจกต์ของคุณพร้อมที่จะเผยแพร่แล้ว คุณสามารถใช้ cargo build --release เพื่อทำการคอมไพล์พร้อมกับการปรับปรุงพัฒนาประสิทธิภาพ คำสั่งนี้จะสร้างไฟล์ไบนารีใน target/release แทนที่จะเป็น target/debug การปรับปรุงพัฒนาประสิทธิภาพจะช่วยให้โค้ด Rust ของคุณรันได้เร็วขึ้น แต่การทำแบบนี้จะทำให้โปรแกรมของคุณคอมไพล์นานขึ้น นี่คือสาเหตุว่าทำไมถึงมีสองโปรไฟล์ที่แตกต่างกัน โปรไฟล์หนึ่งไว้สำหรับในขั้นตอนพัฒนา ที่ซึ่งคุณต้องการคอมไพล์ใหม่อย่างรวดเร็วและบ่อยครั้ง และอีกโปรไฟล์สำหรับคอมไพล์โปรแกรมของคุณที่ทำเสร็จแล้ว ซึ่งคุณจะมอบมันให้กับผู้ใช้โดยที่ไม่ต้องคอมไพล์ใหม่ซ้ำแล้วซ้ำเล่า และยังมีประสิทธิภาพที่รวดเร็วที่สุดที่เป็นไปได้ หากคุณต้องการวัดประสิทธิภาพโค้ดของคุณในขณะที่กำลังรันอยู่ ตรวจสอบให้แน่ใจว่ารันด้วยคำสั่ง cargo build --release และ ทดสอบด้วยไฟล์ใบนารีใน target/release

Cargo ตามแบบแผน

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

แม้ว่าโปรเจกต์ hello_cargo จะเรียบง่าย แต่ตอนนี้คุณก็ใช้เครื่องมือที่ใช้งานจริงมากมายในการประกอบอาชีพ Rust ความเป็นจริงแล้ว ในการทำงานกับโปรเจกต์ที่มีอยู่ คุณสามารถใช้คำสั่งต่อไปนี้เพื่อ ดาวน์โหลดโค้ดของคุณโดยใช้ Git จากนั้นไปที่โฟลเดอร์โปรเจกต์ และทำการคอมไพล์:

$ git clone example.org/someproject
$ cd someproject
$ cargo build

สำหรับข้อมูลเพิ่มเติมเกี่ยวกับ Cargo โปรดดู เอกสารประกอบ

สรุป

คุณได้เริ่มต้นการเดินทางของ Rust อย่างยอดเยี่ยมแล้ว! ในบทนี้คุณได้เรียนรู้เกี่ยวกับ:

  • ติดตั้ง Rust เวอร์ชั่นเสถียรล่าสุดโดยใช้ rustup
  • อัปเดตเป็น Rust เวอร์ชั่นล่าสุด
  • เปิดเอกสารคู่มือบนเครื่อง
  • เขียนและรันโปรแกรม “Hello, world!” โดยใช้ rustc โดยตรง
  • สร้างและรันโปรเจกต์ใหม่โดยใช้แบบแผนของ Cargo

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