CodeBlanks Logo Icon CodeBlanks

Trait ve parametre

Fonksiyon parametresi olarak trait kullanmayı öğrenirsin.

Trait ve parametre

Bir fonksiyon, belirli bir türü değil, belirli bir davranışı isteyebilir. impl Trait sözdizimi "bu trait'i uygulayan herhangi bir tür" demektir:

trait Ozet {
    fn ozet(&self) -> String;
}

fn duyur(x: &impl Ozet) -> String {
    format!("Yeni: {}", x.ozet())
}

duyur artık Ozet uygulayan her türle çalışır: haber, tweet, e-posta... Fonksiyon içinde yalnızca trait'in metotları kullanılabilir.

Generic sözdizimi

impl Trait, aslında bir generic tür parametresinin kısa yazımıdır. İki yazım eşdeğerdir:

fn duyur(x: &impl Ozet) -> String { .. }
fn duyur<T: Ozet>(x: &T) -> String { .. }

Fark birden çok parametrede ortaya çıkar: fn f(a: &impl Ozet, b: &impl Ozet) iki farklı tür kabul eder; fn f<T: Ozet>(a: &T, b: &T) ise ikisinin aynı türden olmasını ister.

Uygulama Duyuru

trait Ozet tanımla ve onu Haber { konu: String } (özet: konu) ile Tweet { yazar: String, metin: String } (özet: @yazar: metin) türlerine uygula. fn duyur(x: &impl Ozet) -> String ile "Rust 2.0 çıktı" haberini ve ece/merhaba tweet'ini ayrı satırlara yazdır.

Başlangıç kodu

main.rs
fn main() {
    // buraya yaz
}

Örnek çözüm

main.rs
trait Ozet {
    fn ozet(&self) -> String;
}

struct Haber {
    konu: String,
}

struct Tweet {
    yazar: String,
    metin: String,
}

impl Ozet for Haber {
    fn ozet(&self) -> String {
        self.konu.clone()
    }
}

impl Ozet for Tweet {
    fn ozet(&self) -> String {
        format!("@{}: {}", self.yazar, self.metin)
    }
}

fn duyur(x: &impl Ozet) -> String {
    format!("Yeni: {}", x.ozet())
}

fn main() {
    let h = Haber { konu: String::from("Rust 2.0 çıktı") };
    let t = Tweet { yazar: String::from("ece"), metin: String::from("merhaba") };
    println!("{}", duyur(&h));
    println!("{}", duyur(&t));
}

Beklenen çıktı

Yeni: Rust 2.0 çıktı
Yeni: @ece: merhaba

Soru ve cevaplar

Dersin sorularını cevaplarıyla birlikte inceleyebilirsin. Kendini denemek istersen dersi interaktif olarak çöz.

1 <code>fn duyur(x: &amp;impl Ozet)</code> içinde <code>x.konu</code> alanına erişilebilir mi?

  • Hayır; derleyici yalnızca Ozet'in sunduklarını bilir Doğru cevap
  • Evet, tür Haber ise
  • Evet, her zaman
  • Yalnızca unsafe ile

Açıklama: Fonksiyon herhangi bir türle çağrılabileceği için yalnızca sözleşmedeki metotlar güvenle kullanılabilir.

2 Davranış iste

Soru
fn duyur(x: &____ Ozet) -> String {
    format!("Yeni: {}", x.ozet())
}
Cevap
fn duyur(x: &impl Ozet) -> String {
    format!("Yeni: {}", x.ozet())
}

Açıklama: &impl Ozet, Ozet uygulayan herhangi bir türe referans kabul eder.

3 İmza ve kabul ettiği

Kavram Anlamı
fn f(x: &impl Ozet) Ozet uygulayan her tür
fn f<T: Ozet>(x: &T) Aynısı, generic yazım
fn f<T: Ozet>(a: &T, b: &T) İkisi aynı tür
fn f(x: &Haber) Yalnızca Haber

Orta seviye bölümündeki tüm dersler