Pola Newtype
Bungkus tipe demi keamanan dan kejelasan.
Pola Newtype adalah pelajaran Learn Rust Coding gratis di CoddyKit. Ini adalah pelajaran 2 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Learn Rust Coding, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Learn Rust Coding mencakup 4 pelajaran total.
Apa Itu Newtype?
Newtype adalah struct tuple dengan satu field yang membungkus tipe yang sudah ada untuk memberinya identitas berbeda. struct Meters(f64) merupakan tipe baru sepenuhnya meskipun menyimpan f64 biasa.
Wrapper ini tidak memiliki biaya saat runtime, tetapi memungkinkan compiler menegakkan makna yang tidak dapat ditegakkan oleh tipe primitif mentah.
struct Meters(f64);
struct Seconds(f64);Mencegah Tertukarnya Satuan
Tipe primitif mentah mudah tertukar. Jika jarak dan waktu sama-sama berupa f64, tidak ada yang mencegah Anda menukarnya dalam sebuah pemanggilan.
Membungkus masing-masing dengan newtype tersendiri menjadikan kesalahan tersebut error saat kompilasi, bukan bug yang tidak terlihat.
fn speed(d: Meters, t: Seconds) -> f64 {
d.0 / t.0
}
// speed(Seconds(2.0), Meters(10.0)) -> compile errorMengakses Nilai di Dalamnya
Anda mengakses nilai yang dibungkus melalui indeks tuple .0. Banyak newtype juga menyediakan method atau mengimplementasikan From untuk konversi yang lebih praktis.
struct UserId(u64);
impl UserId {
fn value(&self) -> u64 { self.0 }
}
fn main() {
let id = UserId(42);
println!("id = {}", id.value());
}Mengenkapsulasi Invarian
Buat field di dalamnya menjadi private dan lakukan validasi di konstruktor. Dengan demikian, setiap nilai newtype dijamin valid sehingga kode berikutnya tidak perlu memeriksa ulang.
pub struct Email(String);
impl Email {
pub fn new(s: &str) -> Option<Email> {
if s.contains('@') {
Some(Email(s.to_string()))
} else {
None
}
}
}Aturan Orphan
Rust melarang implementasi trait asing untuk tipe asing. Anda tidak dapat menulis impl Display for Vec<T> karena Anda tidak memiliki trait maupun tipenya.
Aturan ini menjaga koherensi trait tetap benar di seluruh crate, tetapi dapat menghalangi implementasi yang berguna.
Newtype Melewati Aturan Orphan
Karena newtype didefinisikan di crate Anda, kini Anda memiliki tipe lokal dan dapat mengimplementasikan trait apa pun untuk tipe tersebut. Inilah solusi standar untuk mengatasi aturan orphan.
use std::fmt;
struct Wrapper(Vec<String>);
impl fmt::Display for Wrapper {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}]", self.0.join(", "))
}
}Tampilan Wrapper yang Dapat Dijalankan
Di sini, pembungkus dari adegan sebelumnya mulai digunakan. Kita memiliki Wrapper, sehingga mengimplementasikan Display untuknya diperbolehkan dan program mencetak daftar yang digabungkan.
use std::fmt;
struct Wrapper(Vec<String>);
impl fmt::Display for Wrapper {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{}]", self.0.join(", "))
}
}
fn main() {
let w = Wrapper(vec!["a".into(), "b".into()]);
println!("{}", w);
}Membatasi Permukaan API
Membungkus tipe yang berdaya kuat memungkinkan Anda mengekspos hanya sebagian fungsi yang aman. NonEmptyVec dapat menyembunyikan metode yang mengubah isi sehingga nilainya tidak dapat menjadi kosong, sekaligus mempertahankan invarian tersebut.
pub struct NonEmptyVec<T>(Vec<T>);
impl<T> NonEmptyVec<T> {
pub fn new(first: T) -> Self {
NonEmptyVec(vec![first])
}
pub fn first(&self) -> &T {
&self.0[0]
}
}Abstraksi Tanpa Biaya
Newtype dengan satu bidang memiliki tata letak memori yang sama dengan nilai yang dibungkusnya. Kompilator mengoptimalkan pembungkus tersebut, sehingga keamanan di sini benar-benar tidak menimbulkan biaya saat runtime.
Menambahkan #[repr(transparent)] menjamin tata letak yang identik, yang penting untuk FFI.
#[repr(transparent)]
struct Celsius(f64);Menurunkan Trait pada Newtype
Newtype sering menurunkan trait standar agar berperilaku seperti nilai di dalamnya jika sesuai. Penurunan ini membuatnya tetap praktis digunakan sebagai kunci, untuk perbandingan, dan untuk keluaran debug.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct ProductId(u32);
fn main() {
let a = ProductId(7);
let b = a.clone();
println!("{:?} == {:?}: {}", a, b, a == b);
}Newtype versus Alias Tipe
Jangan samakan newtype dengan alias tipe. type Meters = f64 hanyalah nama; tipe tersebut tetap merupakan f64 dan tidak memberikan keamanan tambahan.
Newtype struct Meters(f64) adalah tipe yang benar-benar berbeda dan dapat dipisahkan oleh kompilator.
type Km = f64; // alias: interchangeable with f64
struct Mi(f64); // newtype: distinct from f64Pemeriksaan Singkat
Tentukan alasan newtype membantu, sedangkan alias tipe tidak.
Rangkuman
Pola newtype membungkus tipe yang sudah ada dalam struct tuple satu bidang untuk mendapatkan identitas yang berbeda tanpa biaya runtime. Pola ini mencegah tertukarnya nilai, merangkum invarian di balik bidang privat, dan mengatasi aturan orphan sehingga Anda dapat mengimplementasikan trait dari luar.
Berbeda dari alias tipe, newtype adalah tipe nyata yang terpisah.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Pola Newtype” gratis?
Ya — teks lengkap “Pola Newtype” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Learn Rust Coding, upgrade ke CoddyKit PRO. Kursus Learn Rust Coding mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Pola Newtype”?
Bungkus tipe demi keamanan dan kejelasan. Kamu berlatih Learn Rust Coding dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Learn Rust Coding?
Tidak diperlukan pengalaman sebelumnya. Learn Rust Coding di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 2 dari 4.
Berapa lama pelajaran “Pola Newtype” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Learn Rust Coding ini?
Ya. Setiap pelajaran Learn Rust Coding menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.