A.25. Method
Pada chapter ini kita akan belajar tentang method beserta perbedaannya dengan associated function.
A.25.1. Method vs associated function
Method adalah associated item yang hanya bisa diakses lewat instance/object, berbeda dengan associated function yang pengaksesan fungsinya via tipe data struct.
Silakan lihat ilustrasi kode berikut, lalu pelajari penjelasan di bawahnya untuk mencari tau perbedaan associated function vs method.
struct Car {
// ...
}
impl Car {
// ...
}
// associated function
let my_car: Car = Car::new();
// method
let info: String = my_car.info();
- Fungsi
new
di situ adalah associated function milik structCar
. Dengannya object baru bernamamy_car
bertipeCar
dibuat. - Object
my_car
adalah variabel bertipeCar
. Via object tersebut method bernamainfo
diakses. - Method
info
tidak bisa diakses via structCar
. Dan associated functionnew
juga tidak bisa diakses dari instance/objectmy_car
.
Di bahasa pemrograman lain, associated function disebut dengan class method, sedangkan method disebut dengan instance method
Pengaksesan associated function dilakukan menggunakan notasi path dengan separator ::
, contohnya seperti Car::new()
. Sedangkan pengaksesan method menggunakan separator .
, contoh: my_car.info()
.
Agar lebih jelas, mari lanjut ke bagian praktik. Siapkan package dengan struktur seperti berikut:
my_package
│─── Cargo.toml
└─── src
│─── main.rs
└─── models.rs
Buka file models.rs
, isi dengan deklarasi struct Car
berikut diikuti dengan blok kode impl
untuk associated items-nya.
#[derive(Debug)]
pub struct Car {
brand: String,
model: String,
manufacture_year: i32
}
impl Car {
// ...
}
A.25.2. Deklarasi method
Cara deklarasi method mirip dengan associated function, perbedaannya adalah parameter pertama harus diisi dengan &self
pada deklarasi method. Parameter tersebut menjadi identifier apakah fungsi merupakan associated function atau method.
Object
self
merupakan representasi dari current instance atau current object.Statement
&self
artinya kita melakukan operasi borrowing terhadap objectself
.Lebih jelasnya mengenai borrowing dibahas pada chapter terpisah.
Silakan tambahkan associated function bernama new
dan method bernama info
berikut. Tulis keduanya dalam blok kode impl
.
// ...
impl Car {
pub fn new(brand: String, model: String) -> Self {
Self { brand, model, manufacture_year: 0 }
}
pub fn info(&self) -> String {
if self.manufacture_year == 0 {
format!("{} model {}", self.brand, self.model)
} else {
format!(
"{} model {}, manufactured at {}",
self.brand,
self.model,
self.manufacture_year
)
}
}
}
Bisa dilihat, deklarasi method adalah mirip dengan fungsi biasa, perbedaannya ada pada deklarasi parameter pertama fungsi yang diisi dengan &self
.
Cara mengakses property milik current object dari dalam method adalah menggunakan keyword self
, contohnya seperti self.brand
, self.model
, dan self.manufacture_year
, pemanggilan ketiganya adalah mengarah ke value property milik current object (self
).
Selanjutnya panggil keduanya di fungsi main
.
mod models;
fn main() {
let car = models::Car::new(
String::from("Mercedes-Benz"),
String::from("Vision Gran Turismo")
);
println!("car: {:?}", car);
let info = car.info();
println!("info: {:?}", info);
}
Bisa dilihat, variabel car
adalah instance dari struct models::Car
, dibuat menggunakan associated function models::Car::new
. Dari variabel tersebut kemudian diakses method info
.
Jalankan program untuk melihat hasilnya.
◉ Naming convention method
Sesuai anjuran di halaman dokumentasi Rust, snake case digunakan dalam penamaan method. Contoh:
impl NamaStruct {
fn nama_method(&self) {
// ...
}
}
A.25.3. Method parameter
Ok, penulis rasa sudah cukup jelas perihal perbedaan associated function dengan method. Sekarang, bagaimana dengan method yang ada parameternya? Cara deklarasinya adalah cukup dengan menuliskan parameter yang diinginkan setelah &self
.
Lanjut ke praktik berikutnya. Silakan buat method baru bernama congratulate
yang memiliki 1 buah parameter bertipe String
, dengan tugas adalah menampilkan pesan selamat.
// ...
impl Car {
// ...
pub fn congratulate(&self, name: String) {
println!("hello {}", name);
println!("congrats with your new car {}", self.info());
println!("vroooom vroooooooommmmm!");
}
}
Dalam method congratulate
ada statement pemanggilan method info
, yang return value-nya ikut di-print. Notasi self.nama_method()
digunakan untuk pemanggilan method dari dalam method. Mirip seperti pemanggilan property yaitu self.nama_property
.
Selanjutnya, panggil method congratulate
di fungsi main
. Isi argumen pemanggilan method dengan sebuah String
.
// ...
fn main() {
let car = models::Car::new(
String::from("Mercedes-Benz"),
String::from("Vision Gran Turismo")
);
car.congratulate(String::from("Sylvanas Windrunner"));
}
Meskipun pada definisi method parameter pertama adalah &self
, pada saat pemanggilan method yang menjadi parameter pertama adalah parameter setelah &self
yaitu name
.
A.25.4. Struct property mutability via method
Nilai property struct bisa diubah dari dalam method. Pada bagian ini kita akan buat method baru untuk struct Car
dengan nama set_manufacture_year
. Method ini bertugas untuk melakukan perubahan nilai property manufacture_year
.
Silakan tulis kode berikut:
// ...
impl Car {
// ...
pub fn set_manufacture_year(&self, year: i32) {
self.manufacture_year = year
}
}
Hmm, tapi kenapa terdeteksi error? Penyebabnya error tersebut adalah karena mutable reference tidak digunakan dalam pengaksesan current object yang padahal ada operasi mutable atau perubahan nilai terhadap property di situ. Syntax &self
artinya operasi peminjaman object self
adalah read only.
Cara mengambil mutable reference dari object self
adalah dengan menggunakan &mut self
. Cara tersebut kurang lebih sama seperti pengambilan mutable reference dari variabel biasa.
Ok, sekarang kita coba modifikasi deklarasi method set_manufacture_year
menjadi seperti berikut:
// ...
impl Car {
// ...
pub fn set_manufacture_year(&mut self, year: i32) {
self.manufacture_year = year
}
}
Lalu panggil method set_manufacture_year
di fungsi main
.
// ...
fn main() {
let mut car = models::Car::new(
String::from("Mercedes-Benz"),
String::from("Vision Gran Turismo")
);
let info = car.info();
println!("info: {:?}", info);
car.set_manufacture_year(2013);
let detailed_info = car.info();
println!("detailed info: {:?}", detailed_info);
}
Jalankan program, lihat hasilnya.
Setelah manufacture_year
di-set, method info
mengembalikan pesan yang berbeda. Dari sini bisa disimpulkan bahwa method set_manufacture_year
sukses menjalankan tugasnya untuk mengubah property manufacture_year
.
A.25.5. Generic pada method
Pembahasan mengenai generic pada method ada pada chapter Generics.
Catatan chapter 📑
◉ Source code praktik
github.com/novalagung/dasarpemrogramanrust-example/../method