fn main() {
let mut user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
user1.email = String::from("anotheremail@example.com");
println!("User1's email: {}",user1.email)
}
.
notation. compare to R : user1$email
fn build_user(email: String, username: String) -> User {
User {
active: true,
username: username,
email: email,
sign_in_count: 1,
}
}
fn build_user(email: String, username: String) -> User {
User {
active: true,
username,
email,
sign_in_count: 1,
}
}
var = var
with just var
User
from an existing instance user1
user1
because we moved the username into user2
user1
would ok.struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
Color
and Point
.0
, .1
etc.struct User {
active: bool,
username: &str,
email: &str,
sign_in_count: u64,
}
fn main() {
let user1 = User {
active: true,
username: "someusername123",
email: "someone@example.com",
sign_in_count: 1,
};
}
String
)Calculate the area of a rectangle
fn main() {
let width1 = 30;
let height1 = 50;
println!(
"The area of the rectangle is {} square pixels.",
area(width1, height1)
);
}
fn area(width: u32, height: u32) -> u32 {
width * height
}
fn main() {
let rect1 = (30, 50);
println!(
"The area of the rectangle is {} square pixels.",
area(rect1)
);
}
fn area(dimensions: (u32, u32)) -> u32 {
dimensions.0 * dimensions.1
}
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
area(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
area
function takes a Rectangle
- clearer intentstruct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {}", rect1);
}
{}
requires implementing std::fmt::Display
trait.{:?}
instead!struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {rect1:?}");
}
Hmm.. “error[E0277]: Rectangle
doesn’t implement Debug
”
But:
= help: the trait `Debug` is not implemented for `Rectangle`
= note: add `#[derive(Debug)]` to `Rectangle` or manually `impl Debug for Rectangle`
Rust can do this automatically but we have to tell it to explicitly.
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {rect1:?}");
}
{:#?}
to ‘pretty print’ the debug info#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let scale = 2;
let rect1 = Rectangle {
width: dbg!(30 * scale), // dbg! captures this intermediate value
height: 50,
};
dbg!(&rect1);
}
stderr
rather then stdout
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle { //implementaiton block
fn area(&self) -> u32 {
self.width * self.height
}
} // end impl block
fn main() {
...
}
impl
blockself
.fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
Uses the .
syntax, automatically passes in self
No need for ->
as in c++, Rust automatically dereferences as required to make this more ergonomic!
p1.distance(&p2);
(&p1).distance(&p2); \\same but more verbose
&self
is shorthand for self : &Self
Self
is shorthand for the object type. (Rectangle
)&self
or &mut self
, borrowing, is most commonself
and taking ownership is rare.impl
block without self
impl
organizes code related to the type in one placeSelf
type, and commonly do in ‘constructor’ functions as above.Rectangle::square(3)
. This should be familiar! String::new()
.impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
self
impl
blocks. Not needed here but this is useful for generics and traits in Chapter 10.Structs let you define custom types
Methods and associated functions for your custom type are defined in impl
blocks, keeping related code together.
Next chapter discusses another custom type: Enums