Generic Traits

Traits نیز می‌توانند generic باشند، درست مانند تایپ و توابع. پارامترهای یک trait زمانی که استفاده می‌شود، تایپ‌های مشخصی پیدا می‌کنند.

#[derive(Debug)]
struct Foo(String);

impl From<u32> for Foo {
    fn from(from: u32) -> Foo {
        Foo(format!("تبدیل شده از integer: {from}"))
    }
}

impl From<bool> for Foo {
    fn from(from: bool) -> Foo {
        Foo(format!("تبدیل‌شده از bool: {from}"))
    }
}

fn main() {
    let from_int = Foo::from(123);
    let from_bool = Foo::from(true);
    println!("{from_int:?}, {from_bool:?}");
}
  • From trait در ادامه دوره پوشش داده خواهد شد، اما تعریف آن در مستندات std ساده است.

  • پیاده‌سازی‌های trait نیازی به پوشش تمام پارامترهای تایپ ممکن ندارند. در اینجا، Foo::from("hello") کامپایل نخواهد شد زیرا پیاده‌سازی <From<&str برای Foo وجود ندارد.

  • traitهای Generic تایپ‌ها را به‌عنوان "ورودی" می‌پذیرند، در حالی که تایپ مرتبط تایپ از "خروجی" هستند. یک trait می‌تواند پیاده‌سازی‌های مختلفی برای تایپ‌های ورودی متفاوت داشته باشد.

  • در واقع، Rust نیاز دارد که حداکثر یک پیاده‌سازی از یک trait برای هر تایپ T تطابق داشته باشد. بر خلاف برخی زبان‌های دیگر، Rust هیچ قاعده‌ای برای انتخاب "مشخص‌ترین" تطابق را ندارد. در حال حاضر، کارهایی برای اضافه کردن این پشتیبانی وجود دارد که به آن ویژه‌سازی می‌گویند.