Methods and self
self is just how the method refers to the very struct it's attached to.In this page:
Reading Data with &self
A method that only needs to read the struct's fields takes &self, an immutable borrow of the instance. This is the most common kind of method.
Example: Reading Data with &self
struct Book {
title: String,
pages: u32,
}
impl Book {
fn summary(&self) -> String {
format!("{} ({} pages)", self.title, self.pages)
}
}
fn main() {
let book = Book { title: String::from("The Rust Book"), pages: 500 };
println!("{}", book.summary());
}
Login to try C/C++/Java/PHP code in the editor
Modifying Data with &mut self
A method that changes one of the struct's fields must take &mut self, a mutable borrow, and the variable holding the instance must itself be declared mut.
Example: Modifying Data with &mut self
struct Counter {
value: i32,
}
impl Counter {
fn increment(&mut self) {
self.value += 1;
}
}
fn main() {
let mut counter = Counter { value: 0 };
counter.increment();
counter.increment();
println!("Counter: {}", counter.value);
}
Login to try C/C++/Java/PHP code in the editor
Consuming self
A method that takes plain self (no &) takes full ownership of the instance, consuming it. This is used when a method transforms a value into something else and the original should no longer be usable.
Example: Consuming self
struct Wrapper {
value: String,
}
impl Wrapper {
fn unwrap(self) -> String {
self.value
}
}
fn main() {
let wrapped = Wrapper { value: String::from("inside") };
let inner = wrapped.unwrap();
println!("{}", inner);
}
Login to try C/C++/Java/PHP code in the editor
Dot Syntax Handles Referencing Automatically
When you call instance.method(), Rust automatically inserts the right amount of referencing or dereferencing to match what the method's self parameter expects, so you rarely need to write (&instance).method() manually.
Example: Dot Syntax Handles Referencing Automatically
struct Temperature {
celsius: f64,
}
impl Temperature {
fn to_fahrenheit(&self) -> f64 {
self.celsius * 9.0 / 5.0 + 32.0
}
}
fn main() {
let temp = Temperature { celsius: 20.0 };
println!("{}F", temp.to_fahrenheit());
}
Login to try C/C++/Java/PHP code in the editor
- Writing
selfwhen you meant&self, which would move the struct into the method instead of just borrowing it. - Forgetting
&mut selfis required for any method that modifies one of the struct's own fields. - Calling a method as
Type::method(instance)when the simplerinstance.method()dot-call syntax is clearer and idiomatic.
&selfborrows the instance immutably, letting a method read its fields without taking ownership.&mut selfborrows the instance mutably, letting a method modify its fields.- Plain
self(without&) takes ownership of the instance, consuming it -- used less often, typically for conversions. - Dot-call syntax
instance.method()automatically handles referencing/dereferencingselffor you.
Chapter Quiz — Complete all 7 topics to unlock
0/7 topics done
Complete these topics first: