Learn Rust Coding · บทเรียน

อนุประโยค where และขอบเขตหลายรายการ

ทำให้ลายเซ็นที่ซับซ้อนอ่านง่าย

บทเรียน 4 จาก 413 ขั้นตอน

อนุประโยค where และขอบเขตหลายรายการ เป็นบทเรียน Learn Rust Coding ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Learn Rust Coding และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

เมื่อข้อกำหนดแบบแทรกอ่านยาก

ข้อกำหนดแบบแทรก เช่น <T: Display + Clone, U: Debug + Default> จะอ่านยากขึ้นเมื่อมีจำนวนมากขึ้น Rust จึงมีส่วนคำสั่ง where เป็นทางเลือกที่อ่านง่ายกว่า

ส่วนคำสั่งนี้ย้ายข้อจำกัดลงไปไว้ใต้ลายเซ็น ทำให้รายการพารามิเตอร์สั้นลง

ส่วนคำสั่ง where พื้นฐาน

ส่วนคำสั่ง where จะอยู่ระหว่างชนิดค่าที่คืนกลับกับบอดี แต่ละบรรทัดจะแสดงชนิดหนึ่งชนิดและข้อกำหนดของชนิดนั้น

ลายเซ็นทั้งสองแบบนี้มีความหมายเหมือนกันทุกประการ เพียงแต่รูปแบบ where อ่านได้ดีกว่า

use std::fmt::Display;

fn show<T>(value: T)
where
    T: Display,
{
    println!("{}", value);
}

ข้อกำหนดหลายรายการใน where

คุณสามารถใส่ข้อจำกัดหลายรายการ โดยใส่หนึ่งรายการต่อพารามิเตอร์ชนิดและคั่นด้วยจุลภาค แต่ละรายการสามารถรวมเทรตด้วย + ได้

วิธีนี้ช่วยให้ลายเซ็นที่มีรายละเอียดมากยังอ่านได้ แทนที่จะอัดทุกอย่างไว้ในบรรทัดเดียว

use std::fmt::{Display, Debug};

fn report<T, U>(a: T, b: U)
where
    T: Display + Clone,
    U: Debug,
{
    println!("{} {:?}", a, b);
}

ตัวอย่างฉบับสมบูรณ์

โปรแกรมนี้ใช้ส่วนคำสั่ง where ที่กำหนดให้ใช้งาน Display ได้ โปรแกรมจะทำงานและพิมพ์อาร์กิวเมนต์แต่ละตัวพร้อมป้ายกำกับ

สังเกตว่าส่วนหัวของฟังก์ชันยังคงอ่านง่าย แม้จะมีข้อกำหนดแนบอยู่

use std::fmt::Display;

fn label<T>(name: &str, value: T)
where
    T: Display,
{
    println!("{} = {}", name, value);
}

fn main() {
    label("age", 30);
    label("city", "Oslo");
}

ข้อกำหนดที่คอมไพเลอร์เขียนแบบแทรกไม่ได้

ข้อกำหนดบางอย่างเขียนได้เฉพาะในส่วนคำสั่ง where เช่น ข้อกำหนดบนชนิดที่เกี่ยวข้องหรือชนิดที่ถูกอ้างอิง ไวยากรณ์แบบแทรกไม่สามารถแสดง where Vec<T>: Clone ได้

ดังนั้นรูปแบบ where จึงแสดงข้อกำหนดได้มากกว่าอย่างชัดเจน

fn duplicate<T>(items: Vec<T>) -> (Vec<T>, Vec<T>)
where
    Vec<T>: Clone,
{
    (items.clone(), items)
}

การรวมเทรตมาตรฐาน

ข้อกำหนดที่พบได้บ่อยในการใช้งานจริงมักรวมความสามารถด้านการจัดลำดับ การคัดลอก และการพิมพ์เข้าด้วยกัน max_of แบบเจเนอริกนี้ค้นหาสมาชิกที่มีค่ามากที่สุดในสไลซ์

ส่วนคำสั่ง where จัดกลุ่มเทรตทั้งสามรายการที่อัลกอริทึมต้องใช้ไว้ด้วยกัน

use std::fmt::Display;

fn max_of<T>(items: &[T]) -> &T
where
    T: PartialOrd + Display,
{
    let mut best = &items[0];
    for item in items {
        if item > best { best = item; }
    }
    best
}

การเรียกใช้ max_of

นี่คือตัวอย่างแนวคิดเดียวกันในโปรแกรมที่เรียกใช้ได้ สไลซ์จำนวนเต็มใช้งาน PartialOrd + Display ได้ ดังนั้นการเรียกใช้จึงคอมไพล์และพิมพ์ค่าสูงสุดออกมา

ฟังก์ชันนี้ใช้กับเลขทศนิยมหรือตัวอักษรได้เช่นกัน

fn max_of<T>(items: &[T]) -> &T
where
    T: PartialOrd,
{
    let mut best = &items[0];
    for item in items {
        if item > best { best = item; }
    }
    best
}

fn main() {
    let nums = [3, 7, 1, 9, 4];
    println!("{}", max_of(&nums));
}

where บนบล็อก impl

ส่วนคำสั่ง where สามารถแนบกับบล็อก impl ได้เช่นกัน วิธีนี้จะเพิ่มเมธอดก็ต่อเมื่อชนิดที่จัดเก็บใช้งาน Display ได้

อินสแตนซ์ที่ T ไม่ใช่ Display จะไม่มีเมธอดนี้

use std::fmt::Display;

struct Holder<T> { item: T }

impl<T> Holder<T>
where
    T: Display,
{
    fn print(&self) {
        println!("{}", self.item);
    }
}

ข้อกำหนดจำนวนมากในครั้งเดียว

ส่วนติดต่อเจเนอริกที่ใช้งานจริงมักต้องการหลายเทรตต่อหนึ่งพารามิเตอร์ ลายเซ็นนี้กำหนดให้มีการโคลน การตรวจสอบข้อผิดพลาด และค่าเริ่มต้น

ส่วนคำสั่ง where ช่วยให้อ่านง่าย แม้ชนิดหนึ่งชนิดจะมีข้อกำหนดถึงสามรายการ

use std::fmt::Debug;

fn build<T>() -> T
where
    T: Default + Clone + Debug,
{
    let v = T::default();
    v.clone()
}

การเลือกใช้แบบแทรกหรือ where

ใช้ข้อกำหนดแบบแทรกเมื่อมีข้อจำกัดง่าย ๆ หนึ่งหรือสองรายการ เปลี่ยนไปใช้ where เมื่อมีพารามิเตอร์หลายตัว รายการเทรตยาว หรือข้อกำหนดบนชนิดที่ซับซ้อน

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

where กับช่วงอายุ

ส่วนคำสั่ง where สามารถระบุความสัมพันธ์ของช่วงอายุควบคู่กับข้อกำหนดเทรตได้ ช่วยจัดระเบียบลายเซ็นเจเนอริกที่มีข้อจำกัดทั้งสองประเภท

ในที่นี้ ส่วนคำสั่งกำหนดให้ T มีอายุยืนกว่าช่วงอายุ 'a

fn keep<'a, T>(value: &'a T) -> &'a T
where
    T: 'a,
{
    value
}

ตรวจสอบความเข้าใจ

ทดสอบความเข้าใจของคุณเกี่ยวกับส่วนคำสั่ง where และข้อกำหนดหลายรายการ

สรุปทบทวน

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

ข้อกำหนดแบบแทรกและแบบ where คอมไพล์เหมือนกัน ดังนั้นให้เลือกแบบที่อ่านได้ชัดเจนกว่า

เริ่มต้นได้ฟรี

เรียนรู้ Rust ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
39
บทเรียน
144

คำถามที่พบบ่อย

บทเรียน “อนุประโยค where และขอบเขตหลายรายการ” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “อนุประโยค where และขอบเขตหลายรายการ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Learn Rust Coding ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Learn Rust Coding มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “อนุประโยค where และขอบเขตหลายรายการ”

ทำให้ลายเซ็นที่ซับซ้อนอ่านง่าย คุณปฏิบัติ Learn Rust Coding ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Learn Rust Coding หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Learn Rust Coding บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “อนุประโยค where และขอบเขตหลายรายการ” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Learn Rust Coding นี้ได้ไหม

ได้ บทเรียน Learn Rust Coding ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชันแบบ泛用
  2. struct และ enum แบบ泛用
  3. ขอบเขตของ trait
  4. อนุประโยค where และขอบเขตหลายรายการ
← กลับไปที่ Learn Rust Coding