struct

from The Rust Programming Language

struct name {
	value: type
}

Structs are similar to tuples, discussed in “The Tuple Type” section, in that both hold multiple related values. Like tuples, the pieces of a struct can be different types. Unlike with tuples, in a struct you’ll name each piece of data so it’s clear what the values mean. Adding these names means that structs are more flexible than tuples: You don’t have to rely on the order of the data to specify or access the values of an instance.

To define a struct, we enter the keyword struct and name the entire struct. A struct’s name should describe the significance of the pieces of data being grouped together. Then, inside curly brackets, we define the names and types of the pieces of data, which we call fields. For example, Listing 5-1 shows a struct that stores information about a user account.

Example struct

struct User { 
	active: bool, 
	username: String, 
	email: String, 
	sign_in_count: u64, 
}

You can call a struct from a function.

Example struct from function

// struct declared previously
   fn build_user(email: String, username: String) -> User{
        User{
            active: true,
            email,
            username,
            sign_in_count: 1,
        }
        
       let user3 = build_user("email@email.com".to_string(), "username".to_string());
    println!("The user's email is {} and the sign-in count is {}", user3.email, user3.sign_in_count);

You can create instances from other instances. Use the syntax ..struct1 to fill in values from that instance

Example instances from instance

    let user2 = User{
        email: String::from("another@m.com");
        ..user1
    }

Tuple structs are like other structs but don't have named values

Example tuple struct

struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

let black = Color(0, 0, 0);
let white = Color(255, 255, 255);

Unit-like structs have no fields and used when you need a type to implement a trait but don't need to store data.

Example unit-like struct

``
    struct AlwaysEqual;   let subject = AlwaysEqual;  

e.g.
.push_str("") -  Appends a string slice (&str) to the end of a String.
.len() - Calculate lentgh of a collection, returning the number of elements or bytes it contains as a usize value.

from The Rust Programming Language

Methods are similar to functions: We declare them with the fn keyword and a name, they can have parameters and a return value, and they contain some code that’s run when the method is called from somewhere else. Unlike functions, methods are defined within the context of a struct (or an enum or a trait object, which we cover in Chapter 6 and Chapter 18, respectively), and their first parameter is always self, which represents the instance of the struct the method is being called on.
...
The main reason for using methods instead of functions, in addition to providing method syntax and not having to repeat the type of self in every method’s signature, is for organization. We’ve put all the things we can do with an instance of a type in one impl block rather than making future users of our code search for capabilities of Rectangle in various places in the library we provide.

impl

Implementations of functionality for a type, or a type implementing some functionality.

There are two uses of the keyword impl:

  • An impl block is an item that is used to implement some functionality for a type.
  • An impl Trait in a type-position can be used to designate a type that implements a trait called Trait.

Implementing Functionality for a Type

The impl keyword is primarily used to define implementations on types. Inherent implementations are standalone, while trait implementations are used to implement traits for types, or other traits.

An implementation consists of definitions of functions and consts. A function defined in an impl block can be standalone, meaning it would be called like Vec::new(). If the function takes self, &self, or &mut self as its first argument, it can also be called using method-call syntax, a familiar feature to any object-oriented programmer, like vec.len().

Example

struct Example {
    number: i32,
}

impl Example {
    fn boo() {
        println!("boo! Example::boo() was called!");
    }

    fn answer(&mut self) {
        self.number += 42;
    }

    fn get_number(&self) -> i32 {
        self.number
    }
}
: Â