Kelas #
Rust tidak memiliki konsep kelas seperti dalam bahasa pemrograman berorientasi objek tradisional seperti Java, C++, atau Python. Namun, Rust memiliki fitur-fitur lain yang menyediakan fungsionalitas serupa yang dapat digunakan untuk mencapai tujuan yang sama dengan kelas dalam bahasa-bahasa tersebut. Fitur-fitur ini meliputi structs, traits, implementasi (impl), dan enums. Dengan menggabungkan fitur-fitur ini, Anda dapat menciptakan tipe data yang kompleks, mengenkapsulasi data dan perilaku, serta mencapai abstraksi dan polimorfisme.
Structs #
Struct di Rust adalah tipe data yang memungkinkan Anda untuk mengelompokkan beberapa nilai dengan berbagai tipe menjadi satu unit. Struct mirip dengan kelas dalam bahasa lain dalam hal pengelompokan data, tetapi tidak memiliki metode yang melekat secara langsung. Metode terkait dengan structs ditambahkan melalui impl
.
Definisi Struct #
Struct dapat didefinisikan dengan menggunakan kata kunci struct
. Struct di Rust bisa berupa struct biasa, tuple struct, atau unit-like struct.
Contoh Struct Biasa:
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
username: String::from("user123"),
email: String::from("[email protected]"),
sign_in_count: 1,
active: true,
};
println!("Username: {}", user1.username);
}
Penjelasan:
User
adalah struct dengan beberapa field, masing-masing memiliki tipe tertentu.user1
adalah instance dari structUser
, dan field dapat diakses menggunakan sintaks.
(dot notation).
Contoh Tuple Struct:
struct Color(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
println!("Red component: {}", black.0);
}
Penjelasan:
Color
adalah tuple struct, di mana nilai-nilai diakses dengan indeks, mirip dengan tuple biasa.
Contoh Unit-like Struct:
struct AlwaysEqual;
fn main() {
let subject = AlwaysEqual;
}
Penjelasan:
AlwaysEqual
adalah unit-like struct tanpa field. Struct semacam ini bisa berguna dalam beberapa konteks seperti marker types.
Implementasi Metode dengan impl
#
Rust memungkinkan Anda untuk menambahkan fungsi (metode) yang terkait dengan struct menggunakan blok impl
. Ini mirip dengan metode dalam kelas di bahasa lain.
Metode Asosiasi (Associated Functions) #
Metode asosiasi adalah fungsi-fungsi yang terkait dengan struct, tetapi tidak membutuhkan instance dari struct tersebut untuk dipanggil. Metode ini sering digunakan sebagai pembuat (constructor) untuk struct.
Contoh Metode Asosiasi:
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn new(width: u32, height: u32) -> Rectangle {
Rectangle { width, height }
}
}
fn main() {
let rect = Rectangle::new(30, 50);
println!("Rectangle: {} x {}", rect.width, rect.height);
}
Penjelasan:
new
adalah metode asosiasi yang digunakan untuk membuat instanceRectangle
baru.
Metode Instance #
Metode instance adalah fungsi yang beroperasi pada instance dari struct. Metode ini mirip dengan metode dalam kelas di bahasa lain dan memiliki parameter pertama self
, yang merupakan referensi ke instance saat ini.
Contoh Metode Instance:
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("Area of the rectangle: {}", rect.area());
}
Penjelasan:
area
adalah metode instance yang mengembalikan luas dariRectangle
.&self
adalah referensi ke instanceRectangle
yang memanggil metodearea
.
Metode Mutable #
Anda juga dapat mendefinisikan metode yang memodifikasi instance struct dengan menggunakan &mut self
.
Contoh Metode Mutable:
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
fn increase_width(&mut self, delta: u32) {
self.width += delta;
}
}
fn main() {
let mut rect = Rectangle { width: 30, height: 50 };
rect.increase_width(10);
println!("New width: {}", rect.width);
}
Penjelasan:
increase_width
adalah metode mutable yang mengubah lebar dariRectangle
.&mut self
memungkinkan metode ini untuk memodifikasi instance.
Traits #
Traits di Rust adalah kumpulan metode yang dapat diimplementasikan oleh berbagai tipe. Traits mirip dengan interface dalam bahasa lain, dan mereka memungkinkan Anda untuk mendefinisikan perilaku yang harus diimplementasikan oleh tipe data yang berbeda.
Definisi Traits #
Contoh Definisi Trait:
trait Describe {
fn describe(&self) -> String;
}
Penjelasan:
Describe
adalah trait yang mendefinisikan metodedescribe
, yang harus diimplementasikan oleh tipe yang mengimplementasikan trait ini.
Mengimplementasikan Traits untuk Struct #
Tipe yang mengimplementasikan trait harus menyediakan definisi untuk semua metode yang ada di trait tersebut.
Contoh Implementasi Traits:
struct Rectangle {
width: u32,
height: u32,
}
impl Describe for Rectangle {
fn describe(&self) -> String {
format!("Rectangle: {} x {}", self.width, self.height)
}
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("{}", rect.describe());
}
Penjelasan:
Rectangle
mengimplementasikan traitDescribe
, sehingga dapat menggunakan metodedescribe
.
Default Method dalam Traits #
Traits di Rust dapat memiliki metode dengan implementasi default, yang berarti tipe yang mengimplementasikan trait tersebut tidak wajib untuk mendefinisikan ulang metode tersebut, kecuali mereka ingin menggantinya.
Contoh Default Method:
trait Describe {
fn describe(&self) -> String {
String::from("This is an object.")
}
}
struct Rectangle {
width: u32,
height: u32,
}
impl Describe for Rectangle {}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
println!("{}", rect.describe());
}
Penjelasan:
Rectangle
mengimplementasikanDescribe
tetapi menggunakan metode defaultdescribe
dari trait.
Polimorfisme dengan Traits #
Dengan menggunakan traits, Rust mendukung polimorfisme, yang memungkinkan fungsi untuk menerima berbagai tipe yang mengimplementasikan trait yang sama.
Contoh Polimorfisme dengan Traits:
trait Describe {
fn describe(&self) -> String;
}
struct Rectangle {
width: u32,
height: u32,
}
impl Describe for Rectangle {
fn describe(&self) -> String {
format!("Rectangle: {} x {}", self.width, self.height)
}
}
struct Circle {
radius: f64,
}
impl Describe for Circle {
fn describe(&self) -> String {
format!("Circle with radius: {}", self.radius)
}
}
fn print_description(item: &impl Describe) {
println!("{}", item.describe());
}
fn main() {
let rect = Rectangle { width: 30, height: 50 };
let circle = Circle { radius: 10.0 };
print_description(&rect);
print_description(&circle);
}
Penjelasan:
- Fungsi
print_description
menerima referensi ke tipe apa pun yang mengimplementasikan traitDescribe
. - Baik
Rectangle
maupunCircle
dapat diteruskan ke fungsi ini karena keduanya mengimplementasikanDescribe
.
Enums #
Selain structs, Rust memiliki enum yang memungkinkan Anda untuk mendefinisikan tipe yang dapat berupa beberapa varian berbeda. Enums di Rust sangat kuat dan sering digunakan untuk menangani kasus yang berbeda dalam program, mirip dengan sealed class
di beberapa bahasa lain.
Contoh Enum:
enum Shape {
Rectangle { width: u32, height: u32 },
Circle(f64),
Unit,
}
fn main() {
let rect = Shape::Rectangle { width: 30, height: 50 };
let circle = Shape::Circle(10.0);
let unit = Shape::Unit;
match rect {
Shape::Rectangle { width, height } => {
println!("Rectangle: {} x {}", width, height);
}
Shape::Circle(radius) => {
println!("Circle with radius: {}", radius);
}
Shape::Unit => {
println!("Unit variant");
}
}
}
Penjelasan:
Shape
adalah enum yang memiliki beberapa varian dengan tipe data yang berbeda.match
digunakan untuk menangani setiap varian enum secara berbeda.
Modul dan Visibilitas #
Rust menggunakan modul untuk mengorganisir kode, dan mendukung pengendalian
visibilitas (public/private) dengan menggunakan kata kunci pub
.
Contoh Modul dan Visibilitas:
mod shapes {
pub struct Rectangle {
pub width: u32,
pub height: u32,
}
impl Rectangle {
pub fn area(&self) -> u32 {
self.width * self.height
}
}
}
fn main() {
let rect = shapes::Rectangle { width: 30, height: 50 };
println!("Area: {}", rect.area());
}
Penjelasan:
mod shapes
mendefinisikan modulshapes
.pub
membuatRectangle
dan metodenya dapat diakses dari luar modul.
Kesimpulan #
Meskipun Rust tidak memiliki konsep kelas seperti dalam bahasa pemrograman berorientasi objek lainnya, kombinasi structs, traits, impl, dan enums memungkinkan Anda untuk mencapai banyak hal yang biasa dilakukan dengan kelas, termasuk enkapsulasi data, pewarisan perilaku, dan polimorfisme.
Rust mengambil pendekatan yang lebih berorientasi pada tipe dan komposisi daripada pewarisan untuk mencapai abstraksi, yang sejalan dengan filosofi Rust untuk memberikan keamanan memori yang kuat dan kinerja tinggi. Memahami bagaimana menggunakan fitur-fitur ini dengan baik akan membantu Anda menulis kode Rust yang lebih modular, fleksibel, dan aman.