Index
- Guessing Game
- Common Programming Concepts
- Understanding Ownership
- Using Structs
- Enums and Pattern Matching
- Managing Growing Projects with Packages, Crates, and Modules
- Defining Modules to Control Scope and Privacy
- Paths for Referring to an Item in the Module Tree
- Bringing Paths into Scope with the use Keyword
- Separating Modules into Different Files
- Common Collections
- Error Handling
- Generic Types, Traits, and Lifetimes
- Writing Automated Tests
- Object Oriented Programming
- Adding dependancies
- Option Take
- RefCell
- mem
- Data Structure
- Recipe
- Semi colon
- Calling rust from python
- Default
- Crytocurrency With rust
- Function chaining
- Question Mark Operator
- Tests with println
- lib and bin
- Append vector to hash map
- Random Number
- uuid4
- uwrap and option
- Blockchain with Rust
- Near Protocol
- Actix-web
Using Structs
struct User {
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
username: String,
email: String,
sign_in_count: u64,
active: bool,
}
To use a struct after we’ve defined it, we create an instance of that struct by specifying concrete values for each of the fields. We create an instance by stating the name of the struct and then add curly brackets containing
key: value
pairs, where the keys are the names of the fields and the values are the data we want to store in those fields let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
To get a specific value from a struct, we can use dot notation. If we wanted just this user’s email address, we could use
user1.email
wherever we wanted to use this value. 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");
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
user1.email = String::from("anotheremail@example.com");
build_user
function that returns a User
instance with the given email and username. The active
field gets the value of true
, and the sign_in_count
gets a value of 1
fn build_user(email: String, username: String) -> User {
User {
email: email,
username: username,
active: true,
sign_in_count: 1,
}
}
User {
email: email,
username: username,
active: true,
sign_in_count: 1,
}
}
Using the Field Init Shorthand when Variables and Fields Have the Same Name
Because the parameter names and the struct field names are exactly the same, we can use the field init shorthand syntax to rewrite
build_user
so that it behaves exactly the same but doesn’t have the repetition of email
and username
fn build_user(email: String, username: String) -> User {
User {
email,
username,
active: true,
sign_in_count: 1,
}
}
Because the
email
field and the email
parameter have the same name, we only need to write email
rather than email: email
Creating Instances From Other Instances With Struct Update Syntax
It’s often useful to create a new instance of a struct that uses most of an old instance’s values but changes some. You’ll do this using struct update syntax
let user2 = User {
email: String::from("another@example.com"),
username: String::from("anotherusername567"),
active: user1.active,
sign_in_count: user1.sign_in_count,
};
email: String::from("another@example.com"),
username: String::from("anotherusername567"),
active: user1.active,
sign_in_count: user1.sign_in_count,
};
Using struct update syntax, we can achieve the same effect with less code
The syntax
..
specifies that the remaining fields not explicitly set should have the same value as the fields in the given instance.let user2 = User {
email: String::from("another@example.com"),
username: String::from("anotherusername567"),
..user1
};
email: String::from("another@example.com"),
username: String::from("anotherusername567"),
..user1
};
Using Tuple Structs without Named Fields to Create Different Types
You can also define structs that look similar to tuples, called tuple structs. Tuple structs have the added meaning the struct name provides but don’t have names associated with their fields; rather, they just have the types of the fields.
fn main() {
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
Otherwise, tuple struct instances behave like tuples: you can destructure them into their individual pieces, you can use a
.
followed by the index to access an individual value, and so on.Unit-Like Structs Without Any Fields
You can also define structs that don’t have any fields! These are called unit-like structs because they behave similarly to
()
, the unit type. Unit-like structs can be useful in situations in which you need to implement a trait on some type but don’t have any data that you want to store in the type itself.Ownership of Struct Data
It’s possible for structs to store references to data owned by something else, but to do so requires the use of lifetimes
Lifetimes ensure that the data referenced by a struct is valid for as long as the struct is.
Error code:
struct User {
username: &str,
email: &str,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: "someone@example.com",
username: "someusername123",
active: true,
sign_in_count: 1,
};
}
username: &str,
email: &str,
sign_in_count: u64,
active: bool,
}
fn main() {
let user1 = User {
email: "someone@example.com",
username: "someusername123",
active: true,
sign_in_count: 1,
};
}
The compiler will complain that it needs lifetime specifiers: