New Type Idiom

RustRustBeginner
Practice Now

This tutorial is from open-source community. Access the source code

Introduction

In this lab, we explore the newtype idiom, which provides compile-time guarantees by allowing us to create a new type that is distinct from its underlying type. An example is shown where a struct Years is used to represent age in years, and a struct Days is used to represent age in days. By using the newtype idiom, we can ensure that the right type of value is supplied to a program, such as in the age verification function old_enough, which requires a value of type Years. Additionally, we learn how to obtain the value of a newtype as its underlying type using tuple or destructuring syntax.

Note: If the lab does not specify a file name, you can use any file name you want. For example, you can use main.rs, compile and run it with rustc main.rs && ./main.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL rust(("`Rust`")) -.-> rust/BasicConceptsGroup(["`Basic Concepts`"]) rust(("`Rust`")) -.-> rust/DataTypesGroup(["`Data Types`"]) rust(("`Rust`")) -.-> rust/FunctionsandClosuresGroup(["`Functions and Closures`"]) rust(("`Rust`")) -.-> rust/DataStructuresandEnumsGroup(["`Data Structures and Enums`"]) rust(("`Rust`")) -.-> rust/AdvancedTopicsGroup(["`Advanced Topics`"]) rust/BasicConceptsGroup -.-> rust/variable_declarations("`Variable Declarations`") rust/DataTypesGroup -.-> rust/integer_types("`Integer Types`") rust/FunctionsandClosuresGroup -.-> rust/function_syntax("`Function Syntax`") rust/FunctionsandClosuresGroup -.-> rust/expressions_statements("`Expressions and Statements`") rust/DataStructuresandEnumsGroup -.-> rust/method_syntax("`Method Syntax`") rust/AdvancedTopicsGroup -.-> rust/traits("`Traits`") subgraph Lab Skills rust/variable_declarations -.-> lab-99352{{"`New Type Idiom`"}} rust/integer_types -.-> lab-99352{{"`New Type Idiom`"}} rust/function_syntax -.-> lab-99352{{"`New Type Idiom`"}} rust/expressions_statements -.-> lab-99352{{"`New Type Idiom`"}} rust/method_syntax -.-> lab-99352{{"`New Type Idiom`"}} rust/traits -.-> lab-99352{{"`New Type Idiom`"}} end

New Type Idiom

The newtype idiom gives compile time guarantees that the right type of value is supplied to a program.

For example, an age verification function that checks age in years, must be given a value of type Years.

struct Years(i64);

struct Days(i64);

impl Years {
    pub fn to_days(&self) -> Days {
        Days(self.0 * 365)
    }
}


impl Days {
    /// truncates partial years
    pub fn to_years(&self) -> Years {
        Years(self.0 / 365)
    }
}

fn old_enough(age: &Years) -> bool {
    age.0 >= 18
}

fn main() {
    let age = Years(5);
    let age_days = age.to_days();
    println!("Old enough {}", old_enough(&age));
    println!("Old enough {}", old_enough(&age_days.to_years()));
    // println!("Old enough {}", old_enough(&age_days));
}

Uncomment the last print statement to observe that the type supplied must be Years.

To obtain the newtype's value as the base type, you may use the tuple or destructuring syntax like so:

struct Years(i64);

fn main() {
    let years = Years(42);
    let years_as_primitive_1: i64 = years.0; // Tuple
    let Years(years_as_primitive_2) = years; // Destructuring
}

Summary

Congratulations! You have completed the New Type Idiom lab. You can practice more labs in LabEx to improve your skills.

Other Rust Tutorials you may like