Struct Methods
Struct methods are like functions, but that are attached
to structs. They are put inside an impl
keyword code
block that has the same name as the struct they are
for. Here we are using an empty struct and adding
a method that prints out "the quick fox". (Notice
that the argument &self
is being passed to the
fn
. That is always the case for methods. (TODO:
talk more about that)
Note that methods are called with ()
.
struct Widget; impl Widget { fn do_output(&self) { println!("the quick fox"); } } fn main() { let thing = Widget; thing.do_output(); }
Using fields
This is done by using &self
which
is alwasy the first argument passed in
struct Widget { alfa: bool, } impl Widget { fn do_output(&self) { println!("alfa is {}", &self.alfa); } } fn main() { let thing = Widget { alfa: true }; thing.do_output(); }
In the more advanced section, point out that
&self
is shorthand for self: &Self
that Rust
provides out of the box.
Talks about using methods instead of functions as some orginaztion and keeping stuff together.
Passing values to methods
struct Widget; impl Widget { fn show_value(&self, value: i32) { println!("Value is {}", value); } } fn main() { let alfa = Widget; alfa.show_value(7); }
Associated Functions
these are like methods, but don't have '&self'
Maybe push this to later in the book.
String::from()
is an associated function.
They are often used to make a new instance of the thing
(e.g. with Widget::new
) by returning Self
The new
is not special or a reserved keyword or
otherwise build into the language.
NOTE: Things are normally writtin in the order:
struct
, impl
, main
but this works and is
easier for me to following when I'm making
learning.
The Self
in the fn
and return value are
aliases to what's named in impl
in this
case Widget
. You can replace Self
with Widget
and it'll still work.
fn main () { let thing = Widget::new(7); println!("thing.alfa {}", thing.alfa); println!("thing.bravo {}", thing.bravo); } impl Widget { fn new(load_value: i32) -> Self { Self { alfa: load_value, bravo: load_value, } } } struct Widget { alfa: i32, bravo: i32, }
Associated function also provide for
name spcing. Here to stucts are given
an associated function with the name
my_value
. Since both are called with
their struct names think get namespaced
and they don't conflict.
fn main() { Alfa::show_message(); Bravo::show_message(); } impl Alfa { fn show_message() { println!("alfa") } } impl Bravo { fn show_message() { println!("bravo") } } struct Alfa; struct Bravo;
Multiple impl blocks
You can make multilpe impl
blocks. The book
says there's not a real reason to do that for the
most part. There will be a later case with
generics types and traits. But kick this out
until then.
struct Widget; impl Widget { fn alfa(&self) { println!("alfa"); } } impl Widget { fn bravo(&self) { println!("bravo"); } } fn main() { let thing = Widget; thing.alfa(); thing.bravo(); }