From and Into are two traits that Rust provides us. They are internally linked.From TraitWe make use of From trait when we want to define a trait to how to create itself from any other type. It provides a very simple mechanism with which we can convert between several types.For example, we can easily convert str into a String.ExampleConsider the example shown below: Live Demofn main() { let my_str = "hello"; let my_string = String::from(my_str); println!("{}", my_string); }OutputhelloWe can even convert our own types.ExampleConsider the example shown below:use std::convert::From; #[derive(Debug)] struct Num { value: i64, } impl ... Read More
Also referred to as enumerations, enums are very useful in certain cases. In Rust, we use enums, as they allow us to define a type that may be one of a few different variants.Enumerations are declared with the keyword enum.Example Live Demo#![allow(unused)] #[derive(Debug)] enum Animal { Dog, Cat, } fn main() { let mut b : Animal = Animal::Dog; b = Animal::Cat; println!("{:?}", b); }OutputCatZero-variant EnumsEnums in Rust can also have zero variants, hence the name Zero-variant enums. Since they do not have any valid values, they cannot be instantiated.Zero-variant enums are equivalent to the never ... Read More
Rust provides us with two types of constants. These are −const − an unchangeable valuestatic − possible mutable value with static lifetime.If we try to assign another value to an already declared const value, the compiler will throw an error.ExampleConsider the example shown below − Live Demostatic LANGUAGE: &str = "TutorialsPoint-Rust"; const THRESHOLD: i32 = 10; fn is_small(n: i32) -> bool { n < THRESHOLD } fn main() { // Error! Cannot modify a `const`. THRESHOLD = 5; println!("Everything worked fine!"); }In the above code, we are trying to modify the value of a variable that is ... Read More
Channels are a medium that allow communication to take place between two or more threads. Rust provides asynchronous channels that enable communication between threads.Channels in Rust allow a unidirectional flow of communication between two endpoints. These two endpoints are Sender and Receiver.ExampleConsider the example shown below −use std::sync::mpsc::{Sender, Receiver}; use std::sync::mpsc; use std::thread; static NTHREADS: i32 = 3; fn main() { let (tx, rx): (Sender, Receiver) = mpsc::channel(); let mut children = Vec::new(); for id in 0..NTHREADS { let thread_tx = tx.clone(); let child = thread::spawn(move || { ... Read More
Casting or explicit conversion is only allowed in Rust, there’s no implicit conversion that the compiler of Rust does for us. It is known that, in many cases, implicit conversion can lead to data losses, which is not a good thing.Rules for converting between different types is pretty similar to C. In Rust though, we make use of as keyword when we want to convert from one type to another.Example:Consider the following example: Live Demo// Suppress all warnings from casts which overflow. #![allow(overflowing_literals)] fn main() { let decimal = 65.43_f32; // Error! No implicit conversion // ... Read More
An array is a data structure that is used to contain objects of the same type T. These objects are stored in contiguous memory locations.In Rust, the arrays are created by making the use of [ ] brackets. It is important that the size of the arrays must be known at the compile time. Also, unlike other languages like Java and C++, the length of the array is part of its type in Rust.[T; length].This means that an array of signature say, [i32, 4], is different from an array with the signature [i32, 5].Arrays can be immutable in nature and there ... Read More
Structs in Rust contains an extra level of visibility. These can be modified by the developers as per his/her convenience.In a normal scenario, the visibility of the struct in Rust is private and it can be made public by making use of the pub modifier.It should be noted that this case of visibility only makes sense when we are trying to access the struct fields from outside the module, from where it is defined.When we are hiding the fields of the struct, we are simply trying to encapsulate the data.ExampleConsider the example shown below −mod my { // A ... Read More
There are two types of errors that occur in Rust, either a recoverable error or an unrecoverable error. We handle the unrecoverable errors with the help of panic!macro and the Result type along with others help in handling the recoverable errors.The Result type is a better version of the Option type which only describes the possible error instead of the possible absence.SignatureThe signature of Result Type is Result < T, E>and it can have only two outcomes.These are: Ok(T): An element T was found.Err(E): An error was found with an element E.Rust also provides different methods that we can associate with ... Read More
Taking care of arguments passed at the runtime is one of the key features of any programming language.In Rust, we access these arguments with the help of std::env::args, which returns an iterator that gives us a string for each passed argument.ExampleConsider the example shown below −use std::env; fn main() { let args: Vec = env::args().collect(); // The first argument is the path that was used to call the program. println!("My current directory path is {}.", args[0]); println!("I got {:?} arguments: {:?}.", args.len() - 1, &args[1..]); }We can pass arguments like this −./args 1 2 3 4 ... Read More
Rust also provides us with a HashSet data structure that is mainly used when we want to make sure that no duplicate values are present in our data structure.If we try to insert a new value into a HashSet that is already present in it, then the previous value gets overwritten by the new value that we insertedBesides the key features, a HashSet is also used to do the following operations −union − Extract all the unique elements in both sets.difference −G ets all the elements that are present in the first set, but not in the second.intersection − Gets ... Read More