Sintaks Batasan Trait
Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan Rust di Coddy. Pelajaran 40 dari 61.
Sejauh ini, kamu telah belajar mendefinisikan trait dan mengimplementasikannya untuk struct. Kamu juga telah menggunakan generik untuk menulis kode yang fleksibel. Sekarang saatnya menggabungkan konsep-konsep ini: menggunakan trait untuk membatasi tipe yang dapat diterima oleh fungsi generik.
Perhatikan fungsi generik yang perlu memanggil method tertentu pada parameternya. Tanpa batasan apa pun, Rust tidak menjamin bahwa tipe T memiliki method tersebut:
fn print_info<T>(item: T) {
println!("{}", item.summarize()); // Error! T mungkin tidak memiliki summarize()
}
Solusinya adalah batasan trait. Dengan menambahkan : TraitName setelah parameter generik, kamu memberi tahu Rust bahwa T harus mengimplementasikan trait tersebut:
trait Summary {
fn summarize(&self) -> String;
}
fn print_info<T: Summary>(item: T) {
println!("{}", item.summarize()); // Sekarang Rust tahu bahwa method ini ada
}
Sintaks <T: Summary> dibaca sebagai "T adalah tipe apa pun yang mengimplementasikan Summary." Sekarang fungsi hanya menerima tipe yang memiliki perilaku yang diperlukan. Jika kamu mencoba memberikan tipe yang tidak mengimplementasikan Summary, compiler akan menolaknya dengan pesan error yang jelas.
Pola ini sangat berguna karena memungkinkanmu menulis kode generik yang tetap dapat mengakses fungsionalitas khusus. Fungsimu tetap fleksibel dan dapat bekerja dengan tipe apa pun, tetapi hanya tipe yang menyediakan perilaku yang kamu perlukan.
Tantangan
MudahMari kita buat sistem notifikasi yang menggunakan batasan trait untuk memastikan hanya pesan dengan format yang benar yang dapat dikirim! Kamu akan membuat fungsi generik yang menerima tipe apa pun yang mengimplementasikan trait tertentu, untuk menunjukkan cara batasan trait membatasi parameter generik.
Kamu akan mengatur kodemu dalam dua file:
notification.rs: Definisikan traitNotifypublik dengan method bernamamessageyang menerima&selfdan mengembalikanString. Lalu, buat dua struct publik yang mengimplementasikan trait ini:Email: dengan fieldsubjectpublik (String). Methodmessage-nya harus mengembalikanEmail: {subject}SMS: dengan fieldcontentpublik (String). Methodmessage-nya harus mengembalikanSMS: {content}
send_notificationyang menerima tipe apa punTyang mengimplementasikan traitNotify. Fungsi ini harus mencetak hasil pemanggilanmessage()pada item tersebut.main.rs: Muat module notifikasi dan gunakan input yang diberikan untuk membuat instanceEmaildanSMS. Panggilsend_notificationdengan masing-masing instance untuk menunjukkan bahwa fungsi generikmu berfungsi dengan tipe apa pun yang mengimplementasikanNotify.
Inti pentingnya adalah send_notification tidak mengetahui tipe konkret yang diterimanya. Fungsi ini hanya mengetahui bahwa tipe tersebut dapat menghasilkan pesan. Batasan trait T: Notify menjamin kemampuan ini.
Output-mu harus menampilkan kedua notifikasi yang dikirim:
Email: {subject}
SMS: {content}Contohnya, dengan input Meeting Tomorrow dan On my way!:
Email: Meeting Tomorrow
SMS: On my way!Kamu akan menerima dua input: subjek email dan isi SMS.
Coba sendiri
mod notification;
use notification::{Email, SMS, send_notification};
fn main() {
// Baca input
let mut subject = String::new();
std::io::stdin().read_line(&mut subject).expect("Failed to read line");
let subject = subject.trim().to_string();
let mut content = String::new();
std::io::stdin().read_line(&mut content).expect("Failed to read line");
let content = content.trim().to_string();
// TODO: Buat instans Email dengan subject
// TODO: Buat instans SMS dengan content
// TODO: Panggil send_notification dengan email
// TODO: Panggil send_notification dengan sms
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Method dan Perilaku
Pengantar Blok ImplementasiParameter SelfMethod MutableFungsi TerkaitBeberapa Blok ImplementasiMethod BerantaiRangkuman: Aksi Persegi Panjang4Proyek: Hewan Peliharaan Virtual
Mendefinisikan Hewan PeliharaanMemberi Makan Hewan Peliharaan2Enkapsulasi dan module
Dasar-Dasar moduleKata Kunci publicField privateGetterSetterRekap: Loker Aman8Trait sebagai Batasan
Sintaks Batasan TraitBeberapa BatasanKlausa whereMengembalikan Tipe dengan TraitRangkuman: Pencetak GenerikLatihan sendiri: Compiler Rust online