CodeBlanks Logo Icon CodeBlanks

GAT

Generic Associated Types (GAT) kavramını öğrenirsin.

GAT

Generic ilişkili türler (GAT), ilişkili türün kendisinin generic parametre (çoğunlukla ömür) almasını sağlar. Böylece bir trait, self'ten ödünç alan bir görünüm türü döndürebilir:

trait Bakilabilir {
    type Bakis<'a> where Self: 'a;
    fn bak<'a>(&'a self) -> Self::Bakis<'a>;
}

struct Kutu(Vec<i32>);
impl Bakilabilir for Kutu {
    type Bakis<'a> = &'a [i32];
    fn bak<'a>(&'a self) -> &'a [i32] { &self.0 }
}

GAT'lar Rust 1.65 ile kararlı hale geldi; "ödünç veren yineleyici" (lending iterator) gibi önceden yazılamayan soyutlamaları mümkün kılar.

Farklı görünümler

Aynı trait farklı türler için farklı ödünç görünümler döndürebilir:

struct Metin(String);
impl Bakilabilir for Metin {
    type Bakis<'a> = &'a str;
    fn bak<'a>(&'a self) -> &'a str { &self.0 }
}

let k = Kutu(vec![1, 2, 3]);
let m = Metin(String::from("merhaba"));
println!("{} {}", k.bak().len(), m.bak());   // 3 merhaba

GAT olmadan ilişkili tür bir ömür alamaz; her çağrıda kopya döndürmek ya da tasarımı değiştirmek gerekirdi.

Uygulama Ödünç görünümler

Yukarıdaki Bakilabilir trait'ini Kutu(Vec<i32>) ve Metin(String) için uygula. Kutu(vec![1, 2, 3]).bak().len() ve Metin("merhaba").bak() sonuçlarını boşlukla yazdır.

Başlangıç kodu

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

Örnek çözüm

main.rs
trait Bakilabilir {
    type Bakis<'a>
    where
        Self: 'a;
    fn bak<'a>(&'a self) -> Self::Bakis<'a>;
}

struct Kutu(Vec<i32>);
struct Metin(String);

impl Bakilabilir for Kutu {
    type Bakis<'a> = &'a [i32];
    fn bak<'a>(&'a self) -> &'a [i32] {
        &self.0
    }
}

impl Bakilabilir for Metin {
    type Bakis<'a> = &'a str;
    fn bak<'a>(&'a self) -> &'a str {
        &self.0
    }
}

fn main() {
    let k = Kutu(vec![1, 2, 3]);
    let m = Metin(String::from("merhaba"));
    println!("{} {}", k.bak().len(), m.bak());
}

Beklenen çıktı

3 merhaba

Soru ve cevaplar

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

1 <code>where Self: 'a</code> neden gerekir?

  • Gerekmez
  • Görünüm 'a kadar yaşayacağı için Self'in de en az o kadar yaşaması gerekir Doğru cevap
  • Gelenek
  • Hız için

Açıklama: Derleyici bu sınırı GAT bildirimlerinde ister; ödünç alınan değerin kaynaktan uzun yaşamaması için.

2 Ömürlü ilişkili tür

Soru
trait Bakilabilir {
    type Bakis____ where Self: 'a;
    fn bak<'a>(&'a self) -> Self::Bakis<'a>;
}
Cevap
trait Bakilabilir {
    type Bakis<'a> where Self: 'a;
    fn bak<'a>(&'a self) -> Self::Bakis<'a>;
}

Açıklama: GAT, ilişkili türe generic parametre ekler.

3 Uygulama ve Bakis türü

Kavram Anlamı
Kutu(Vec<i32>) &'a [i32]
Metin(String) &'a str
Iterator::Item GAT değil
type Bakis<'a> GAT

İleri seviye bölümündeki tüm dersler