Ben Chuanlong Du's Blog

It is never too late to learn.

Struct in Rust

In [ ]:
:timing
:sccache 1
  1. Rust's design is different from traditional OOP programming languages. There is no class in Rust, however, you can achieve it using struct + impl.

  2. Rust does not have the concept of constructor (since Rust even does not have the concept of class). A simple way is to directly create a struct of initialized values. If complicated intermediate operations are required, you can implement a static new method for the struct.

Sized vs ?Sized

Sync vs !Sync

In [4]:
struct Person {
    name: String,
    age: u8,
}

Construct Instances of a Struct

  1. There is only one true way to create an instance of a struct. Taking the struct Person as an example.

     Person {
         name: "Jane Doe",
         age: 30
     }
    
    

    However, this way won't work when a struct contains private fields and you have to initialize an instance of the struct in a different module. The convention in Rust is to create a public new method for constructing instances of a struct.

  2. The Default trait has a default() method for constructing a default instance of a struct. It is suggested that you implement the Default trait if you want to provide a default constructor for a struct.

For more discussions, please refer to the YouTube tutorial Idiomatic Rust - Constructors .

Create an Instance of Person

In [4]:
let p = Person {name: String::from("Ben Du"), age: 30,};
In [5]:
p.name
Out[5]:
"Ben Du"
In [6]:
p.age
Out[6]:
30

Implement a new Method for Constructing Instances

In [6]:
impl Person {
    fn new (name: &str, age: u8) -> Person {
        Person {
            name: name.to_string(),
            age: age,
        }
    }
}
In [7]:
let p2 = Person::new("Ben Du", 30);
In [8]:
p2.name
Out[8]:
"Ben Du"
In [14]:
p2.age
Out[14]:
30

Associated Constants

In [9]:
impl Person {
    const DENOMINATOR: u32 = 4567891;
}
In [11]:
let p = Person::new("Ben Du", 31);
In [12]:
p.name
Out[12]:
"Ben Du"
In [13]:
p.age
Out[13]:
31
In [16]:
Person::DENOMINATOR
Out[16]:
4567891
In [20]:
impl Person {
    fn get_deno() -> u32 {
        return Person::DENOMINATOR
    }
}
In [22]:
let p = Person::new("Ben Du", 32);
In [23]:
p.name
Out[23]:
"Ben Du"
In [24]:
p.age
Out[24]:
32
In [26]:
Person::get_deno()
Out[26]:
4567891

Hash and Eq

Please refer to Hash in Rust for more discussions.

Copy and Clone

Please refer to The Copy and Clone Traits in Rust for more discussions.

Shared Method in Different Struct

There are a few ways to achieve this.

  1. Use a trait and define a shared method as a default implementation in the trait. This is convenient if the shared method does not refer to fields of struct (or only read fields of struct).

  2. Use macro to generate common methods. This way is more complicated and it is not recommended unless the share method is a generic useful method.

  3. Define a base struct with the shared method and include the base struct as a field in other structs. This is called composition (in contrast to inheritance). Composition is preferred over inheritance nowadays.

Functions

Please refer to Functions in Rust for more discussions.

In [ ]:

Comments