Parametreli Traitler
Coddy'nin Rust Journey'sinin Nesne Yönelimli Programlama bölümünün bir parçası. Ders 33 / 61.
Şimdiye kadar trait metotlarımız parametre olarak yalnızca &self aldı. Ancak trait metotları, normal metotlar gibi ek parametreleri kabul edebilir. Bu, onları gerçek dünyadaki işlemler için çok daha kullanışlı hâle getirir.
Bir trait tanımlarken, metot imzalarına ihtiyaç duyduğunuz tüm parametreleri ekleyebilirsiniz:
trait Calculator {
fn add(&self, a: i32, b: i32) -> i32;
fn multiply(&self, a: i32, b: i32) -> i32;
}
Bu Calculator trait'i, &self'e ek olarak her biri iki tamsayı kabul eden iki metot gerektirir. Bu trait'i uygulayan her tür, bu işlemlerin her ikisini de tam olarak bu imzalarla sağlamalıdır.
Bir struct bunu şu şekilde uygulayabilir:
struct BasicCalc;
impl Calculator for BasicCalc {
fn add(&self, a: i32, b: i32) -> i32 {
a + b
}
fn multiply(&self, a: i32, b: i32) -> i32 {
a * b
}
}
Artık bu yöntemleri bağımsız değişkenlerle kullanabilirsiniz:
let calc = BasicCalc;
println!("{}", calc.add(5, 3)); // 8
println!("{}", calc.multiply(4, 7)); // 28
Trait, her yöntemin hangi parametreleri kabul ettiğini tanımlarken uygulama, bu parametrelerin nasıl kullanıldığını tanımlar. Bu, farklı türlerin aynı işlemleri kendi yöntemleriyle gerçekleştirmesine olanak tanır: örneğin bir LoggingCalc, sonucu döndürmeden önce her işlemi yazdırabilir.
Görev
KolayFarklı işlemcilerin metni kendi yöntemleriyle dönüştürebildiği bir dize işleme araç seti oluşturalım! Parametre kabul eden yöntemlere sahip bir TextProcessor trait'i oluşturacak, ardından bunu iki farklı işlemci türü için uygulayacaksın.
Kodunu üç dosyada düzenleyeceksin:
processor.rs: Parametre kabul eden iki yönteme sahip herkese açık birTextProcessortrait'i tanımla:repeat(&self, text: &str, times: u32) -> String: verilen metni belirtilen sayıda tekrarlartruncate(&self, text: &str, max_len: usize) -> String: metni belirtilen maksimum uzunluğa kısaltır
processors.rs: trait'ini uygulayan iki herkese açık yapı oluştur:SimpleProcessor: her tekrarın arasına boşluk koyarak metni tekrarlayan (örneğin, 3 kez tekrarlanan "Hi" metni "Hi Hi Hi" olur) ve maksimum uzunlukta basitçe keserek kısaltan bir birim yapıdırFancyProcessor: tekrarların arasına " * " koyarak metni tekrarlayan (örneğin, 3 kez tekrarlanan "Hi" metni "Hi * Hi * Hi" olur) ve metin kısaltılmışsa "..." ekleyen (yalnızca özgün metin max_len değerinden uzunsa) bir birim yapıdır
main.rs: Modüllerini bir araya getir ve hangi işlemciyi kullandığına bağlı olarak aynı trait yöntemlerinin nasıl farklı sonuçlar ürettiğini göster.
Ana dosyanda her iki işlemciyi oluştur ve bunları test etmek için girdileri kullan. Üç girdi alacaksın: bir metin dizesi, bir tekrar sayısı ve bir maksimum uzunluk.
Her işlemcinin davranışını gösteren dört satır yazdır:
Simple repeat: {result}
Simple truncate: {result}
Fancy repeat: {result}
Fancy truncate: {result}Örneğin, girdiler Hello, 3 ve 4 olduğunda:
Simple repeat: Hello Hello Hello
Simple truncate: Hell
Fancy repeat: Hello * Hello * Hello
Fancy truncate: Hell...Her iki işlemcinin de aynı TextProcessor sözleşmesini yerine getirdiğine, ancak her birinin metni kendine özgü bir şekilde dönüştürdüğüne dikkat et! Trait, yöntemlerin hangi parametreleri kabul ettiğini tanımlarken her uygulama bunları nasıl kullanacağına karar verir!
Üç girdi alacaksın: işlenecek metin, tekrar sayısı (u32 olarak ayrıştır) ve kısaltma için maksimum uzunluk (usize olarak ayrıştır).
Kendin dene
mod processor;
mod processors;
use processor::TextProcessor;
use processors::{SimpleProcessor, FancyProcessor};
fn main() {
// Girdileri oku
let mut text = String::new();
std::io::stdin().read_line(&mut text).expect("Failed to read line");
let text = text.trim();
let mut times_input = String::new();
std::io::stdin().read_line(&mut times_input).expect("Failed to read line");
let times: u32 = times_input.trim().parse().expect("Failed to parse times");
let mut max_len_input = String::new();
std::io::stdin().read_line(&mut max_len_input).expect("Failed to read line");
let max_len: usize = max_len_input.trim().parse().expect("Failed to parse max_len");
// İşlemcileri oluştur
let simple = SimpleProcessor;
let fancy = FancyProcessor;
// TODO: Metni dönüştürmek ve sonuçları yazdırmak için işlemcileri kullan
// Dört satır yazdır:
// Simple repeat: {result}
// Simple truncate: {result}
// Fancy repeat: {result}
// Fancy truncate: {result}
}
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Nesne Yönelimli Programlama bölümündeki tüm dersler
1Metotlar ve Davranış
Uygulama Bloklarına GirişSelf ParametresiDeğiştirilebilir Metotlarİlişkili FonksiyonlarBirden Fazla Uygulama BloğuMetot ZincirlemeÖzet - Dikdörtgen Eylemleri4Proje: Sanal Evcil Hayvan
Evcil Hayvanı TanımlamaEvcil Hayvanı Besleme2Kapsülleme ve Modüller
Modül TemelleriPublic Anahtar KelimesiPrivate AlanlarGetter'larSetter'larÖzet - Güvenli Kasa5Generic Yapılar
Generic Struct'larGeneric MetotlarÇoklu Generic TürlerGeneric FonksiyonlarÖzet - Koordinat Noktası8Sınırlandırıcı Olarak Trait'ler
Trait Sınırlandırıcı SözdizimiÇoklu SınırlandırıcılarWhere CümleciğiTrait'ler ile Tip DöndürmeÖzet - Generic Yazıcı11Rust'ta Tasarım Kalıpları
Newtype KalıbıKompozisyonDrop Trait'iFrom ve IntoÖzet - Smart Pointer Mock3İleri Seviye Enum'lar
Veri İçeren Enum'larEnum MetotlarıVeri Varyantlarını EşlemeOption Enum'ına Yeniden BakışÖzet - Shape Enum6Trait Tanımlama
Trait Nedir?Traitleri UygulamaVarsayılan UygulamalarVarsayılanları Geçersiz KılmaParametreli TraitlerÖzet - Media PlayerKendi başına pratik yap: Online Rust derleyicisi