Skip to content

Latest commit

 

History

History
188 lines (130 loc) · 9.64 KB

File metadata and controls

188 lines (130 loc) · 9.64 KB

06 — Tooling & Workflow (cargo, fmt, clippy, test, doc)

TOC · Prev · Next

Keywords: tooling, testing, modules, playbook

อ่านแบบคน Python:

  • ถ้าอยากเอา “ภาพรวม” ก่อน: จำ 4 คำสั่งแกน check → test → fmt → clippy
  • ถ้าอยาก “ลงมือทำ”: ใช้ cargo check เป็น default แล้วค่อยไล่ step ถัดไป
  • ถ้าติด: เปิด 12-learning-playbook.md

บทนี้สั้นแต่สำคัญ: ทำให้ workflow Rust ลื่นแบบมืออาชีพ

ถ้าคุณมาจาก Python คุณอาจคุ้นกับวงจรประมาณนี้:

  • แก้โค้ด → รัน → เจอ error → แก้ → รันใหม่

Rust ก็ทำแบบนั้นได้ แต่ถ้าจับ workflow ที่ถูก คุณจะรู้สึกว่า:

  • แก้โค้ด → cargo check/cargo test → ได้ feedback ที่ชัด → แก้ต่อแบบไม่เดา

แนวคิดหลักของบทนี้:

  • ให้ compiler + tests + lints เป็น “ระบบ feedback” ที่คอยพาคุณไปทางที่ถูก
  • ลดการเสียเวลาไปกับ bug ที่ตรวจได้ตั้งแต่ก่อนรัน

กรณีศึกษาจากโค้ด Python จริงที่เจอบ่อย (สิ่งที่ควรเลี่ยง):

  • ติดตั้ง dependency ตอน runtime (เช่นเรียก pip install ... ในโค้ด) → พังยาก, reproducibility แย่, และเสี่ยงด้านความปลอดภัย

Rust ชอบให้ “dependencies ถูกประกาศ” และ “สภาพแวดล้อมนิ่ง”:

  • dependencies อยู่ใน Cargo.toml และถูกล็อกด้วย Cargo.lock
  • โค้ดควรจะ “รันได้เหมือนเดิม” ระหว่างเครื่อง dev/CI/production

0) ลำดับที่แนะนำ (สำหรับตอนพัฒนา)

ถ้าคุณกำลังแก้โค้ดอยู่ ให้ยึด 4 ตัวนี้เป็นแกน:

  1. cargo check (เร็วที่สุด)
  • ไล่ type/borrow errors
  1. cargo test
  • ยืนยันพฤติกรรม (ไม่ใช่แค่ compile ผ่าน)
  1. cargo fmt
  • จัดรูปแบบให้มาตรฐาน
  1. cargo clippy
  • เก็บ lint/code smell และ pattern เสี่ยง

ถ้าคุณทำตามลำดับนี้เป็นนิสัย คุณจะรู้สึกว่า “คุมระบบได้” มากขึ้นแบบชัดเจน


1) cargo run, cargo build, cargo check

Python (เทียบคำสั่งที่คุ้น):

  • รันไฟล์: python main.py
  • รันโมดูล: python -m package.module

Rust:

cargo run
cargo build
cargo check
cargo build --release

ความหมายโดยย่อ:

  • cargo run = build + run (เหมาะตอนอยากเห็น behavior)
  • cargo build = build อย่างเดียว (เช็คว่า compile ผ่าน)
  • cargo check = type-check/borrow-check แบบเร็ว (เหมาะตอนยังแก้อยู่)
  • cargo build --release = build แบบ optimized (เหมาะตอนอยากวัด performance/ปล่อยใช้งาน)

จุดต่างที่ควรรู้:

  • cargo จะ cache ผลลัพธ์การ build (incremental) ทำให้แก้เล็ก ๆ แล้วรันเร็วขึ้น
  • ถ้าเจอ error compile: ให้แก้ให้ผ่านก่อนค่อยไปขั้นต่อไป (อย่าพยายาม “รันฝืน”) เพราะ Rust ตั้งใจให้ error ถูกแก้ตั้งแต่ต้นทาง

ทิป: ถ้าคุณรันโปรแกรมผ่าน cargo run แล้วอยากส่ง args ให้ binary ต้องคั่นด้วย --

  • ตัวอย่าง: cargo run -- status

2) Format: cargo fmt

cargo fmt (rustfmt) คือ auto-formatter มาตรฐานของ Rust ecosystem

ทำไมมันสำคัญกว่าที่คิด:

  • เวลาอ่านโค้ด Rust คนมักคาดหวัง format มาตรฐาน → ถ้าทุกไฟล์เหมือนกัน คุณจะโฟกัสที่ “ตรรกะ” ไม่ใช่ “สไตล์”
  • ลด churn ใน code review (ไม่เถียงเรื่องเว้นวรรค/วงเล็บ)

แนวทางใช้งาน:

  • รันก่อน commit/แชร์โค้ด
  • ถ้า IDE รองรับ ให้ตั้ง format-on-save จะช่วยมาก

3) Lint: cargo clippy

cargo clippy คือ linter ที่เก่งมากของ Rust ecosystem

มันช่วยอะไรในทางปฏิบัติ:

  • ชี้ code smell ที่ compile ผ่านแต่ “เสี่ยง” (เช่น clone เกินจำเป็น)
  • ชี้ bug pattern ที่คนเขียนใหม่ ๆ มักพลาด
  • ให้ feedback แบบมีเหตุผล (หลายอันมีข้อความแนะนำพร้อมตัวอย่าง)

วิธีใช้ clippy แล้วไม่หงุดหงิด:

  • มองว่า clippy คือ “รีวิวอัตโนมัติ” ไม่ใช่การจับผิดส่วนตัว
  • แก้ทีละอัน โดยเริ่มจาก warning ที่เกี่ยวกับ correctness ก่อน แล้วค่อยไล่เรื่อง style/perf

4) Tests: cargo test

Test คือ “เบรก” ที่ช่วยให้คุณ refactor ได้เร็วโดยไม่พังเงียบ ๆ

Python (เทียบกับสิ่งที่คุ้น):

  • แบบง่ายสุด: assert ในไฟล์
  • หรือใช้ pytest/unittest

Rust mindset:

  • unit test มักอยู่ใกล้โค้ด (ในไฟล์เดียวกัน) และถูก compile แยกตอน cargo test
  • Rust strict ทำให้ bug เชิงโครงสร้างบางชนิด “ไม่เกิด” ตั้งแต่แรก แต่คุณยังต้อง test พฤติกรรม (business rules) อยู่ดี

ตัวอย่าง (Python):

def add(a: int, b: int) -> int:
    return a + b


def test_add() -> None:
    assert add(1, 2) == 3

Output (example):

(no output — tests pass silently)

Rust:

fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[test]
fn test_add() {
    assert_eq!(add(1, 2), 3);
}

Output (example):

(no output — tests pass silently)

ทิปที่ใช้จริง:

  • ถ้าต้องการเห็น output (println!) ตอน test ผ่านด้วย ให้รัน cargo test -- --nocapture
  • ถ้าต้องการรันแค่บาง test: cargo test name_of_test

5) Docs: cargo doc --open

Rust ecosystem ใช้ doc comments และ cargo doc

  • cargo doc สร้างเอกสารของโปรเจกต์และ dependencies
  • อ่าน docs.rs และ std docs ได้เร็วมาก ถ้าคุณคุ้นกับ pattern ของมัน

6) สรุป workflow ที่ใช้แก้งานจริง

เวลาแก้ปัญหาแบบไม่หลงทาง ให้คิดเป็นวงจร:

  • ทำให้ compile ผ่าน (cargo check)
  • ทำให้พฤติกรรมถูก (cargo test)
  • ทำให้โค้ดอ่านง่าย (cargo fmt)
  • ทำให้หลบ bug pattern (cargo clippy)

7) แบบฝึกหัด

  1. สร้างโปรเจกต์ใหม่แล้วรัน cargo fmt และ cargo clippy

  2. เพิ่ม test 1 ตัวและรัน cargo test

  3. ลองทำให้ test fail 1 ครั้ง แล้วอ่าน output ว่ามันช่วยบอกอะไร

  4. (เสริม) ลองสร้างสถานการณ์ “dependency หาย” แล้วสังเกต workflow ที่ดี

  • Python: ถ้าโปรเจกต์พึ่ง pip install ตอน runtime คุณจะเจอความไม่แน่นอน (เครื่องนี้มี/เครื่องนั้นไม่มี)
  • Rust: ทดลองเพิ่ม dependency ใน Cargo.toml แล้วรัน cargo build/cargo check ดูว่า error ชัดขึ้นยังไง