DEV Community

Cover image for From and Into Traits in Rust Programming Language
Ankit for Int Main

Posted on • Originally published at intmain.co

From and Into Traits in Rust Programming Language

If you are new to Rust then From (From) and Into (into) traits might sound confusing to you, but they are interesting trait systems of Rust. In this tutorial, we will learn From and Into traits with examples.

The From and Into traits are inherently linked, and this is actually part of its implementation. If you are able to convert type A from type B, then it should be easy to believe that we should be able to convert type B to type A.

From Trait

The From trait provides the ability to create a conversion trait, which allows you to convert values of one type into values of another type. For example, the standard library implements impl From<&'_ str> for String which allows you to generate a String from a &str.

For example, we can easily convert a &str into a String

let my_str = "Hello Intmain";
let my_string = String::from(my_str);
Enter fullscreen mode Exit fullscreen mode

Another example of from trait:

Suppose we want to implement our own From trait From for SplitName. This would allow us to split any given name separated by whitespace into Struct containing first and last names. This can be done easily using From trait. Below is an example of the same.

use std::convert::From;

#[derive(Debug)]
struct SplitName{
    first_name: String,
    last_name: String,
}
impl From<String> for SplitName {
    fn from(item: String) -> Self {

        let name_vector:Vec<&str> = item.split_whitespace().collect();
        SplitName { first_name : name_vector[0].to_string(), last_name :name_vector[1].to_string(), }
    }
}
fn main() {
    let from_example = SplitName::from("Int Main".to_string());
    println!("The name is {:?}", from_example);
}
Enter fullscreen mode Exit fullscreen mode

Output

The name is: SplitName { first_name: "Int", last_name: "Main" }
Enter fullscreen mode Exit fullscreen mode

The From is also very useful when performing error handling. When constructing a function that is capable of failing, the return type will generally be of the form Result.

Note: This trait must not fail. The From trait is intended for perfect conversions. If the conversion can fail or is not perfect, use TryFrom

Into Trait

The Into trait is the opposite of the From trait. The Implementation of From automatically provides the implementation of Into trait and one should avoid implementing Into trait and instead implement From trait.

Using the Into trait will typically require specification of the type to convert into as the compiler is unable to determine this most of the time.

For example, we can easily convert a &str into a String

let my_str = "Hello Intmain";
let my_string :String = my_str.into();
Enter fullscreen mode Exit fullscreen mode

Taking the above example again to split any given name separated by whitespace into Struct containing first and last names, we can split the name directly by calling the .into() to the given name after converting it into the string. Here we are required to provide the specification as: let into_example :SplitName = "Int Main".to_string().into();

Here’s the complete code to convert a name into SplitName using the From and Into traits:

use std::convert::From;

#[derive(Debug)]
struct SplitName{
    first_name: String,
    last_name: String,
}
impl From<String> for SplitName {
    fn from(item: String) -> Self {

        let name_vector:Vec<&str> = item.split_whitespace().collect();
        SplitName { first_name : name_vector[0].to_string(), last_name :name_vector[1].to_string(), }
    }
}
fn main() {
    let from_example = SplitName::from("Int Main".to_string());
    println!("The name is using from: {:?}", from_example);

    let into_example :SplitName = "Int Main".to_string().into();
    println!("TThe name is using into: {:?}", into_example);
}
Enter fullscreen mode Exit fullscreen mode

Output

The name is using from: SplitName { first_name: "Int", last_name: "Main" } 
The name is using into: SplitName { first_name: "Int", last_name: "Main" }
Enter fullscreen mode Exit fullscreen mode

You’re free to use into() and from() both and it’s up to you to decide which one feels the most expressive to your code but prefers using Into over From when specifying trait bounds on a generic function to ensure that types that only implement Into can be used as well.

**Note: **This trait must not fail. If the conversion can fail, use TryInto.

Conclusion

The “From” and “Into” traits in Rust are used to perform type conversions. The “From” trait allows you to convert values of one type into values of another type by implementing the from method. The “Into” trait is a simplified version of the “From” trait and allows for a more straightforward conversion by implementing the into method.

The main difference between the two is that the “Into” trait assumes that the conversion will always be successful, while the “From” trait allows for the possibility of a failed conversion, which is achieved by returning a Result type from the from method implementation, which can be either Ok with the converted value, or Err with an error description.


This post was originally published at intmain.co

Top comments (0)