Rust
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.
Örnek çözümü göster
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());
}
Kendini test et
-
<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
- Gelenek
- Hız için
Cevabı göster
Görünüm 'a kadar yaşayacağı için Self'in de en az o kadar yaşaması gerekir — Derleyici bu sınırı GAT bildirimlerinde ister; ödünç alınan değerin kaynaktan uzun yaşamaması için.
-
Ömürlü ilişkili tür
trait Bakilabilir {
type Bakis____ where Self: 'a;
fn bak<'a>(&'a self) -> Self::Bakis<'a>;
}
Cevabı göster
trait Bakilabilir {
type Bakis<'a> where Self: 'a;
fn bak<'a>(&'a self) -> Self::Bakis<'a>;
}
-
Uygulama ve Bakis türü
- Kutu(Vec<i32>)
- &'a [i32]
- Metin(String)
- &'a str
- Iterator::Item
- GAT değil
- type Bakis<'a>
- GAT
Sıradaki ders: Supertrait