Introduction to Rust programming language



For a long time, we are writing highly efficient applications/algorithms in C/C++.  C/C++ is always served the purpose and when it comes to speed and efficiency no other programming language is close to C/C++.
But at the same time, it requires high skills and experience for designing and development in C/C++. poorly designed applications always suffer when they come into the maintenance phase.

Memory safety has always been an issue for large scale C/C++ applications. People started using other high-level programming languages where speed/efficiency and high memory footprint are not only the prime requirement.
Combination of C/C++ with other high-level languages is also the trend now, core processing is managed by the C/C++ modules with non-critical modules are implemented in other high-level languages. 
This mix and match are widely accepted but these techniques suffer from poor support for C/C++ as these high level-languages are never designed for this purpose. For the web development, mobile application development, analytics, machine learning etc, a lot of good things are happening. But for system programming still, We can not see many new things.

Finally,  Mozilla research lab came with an entirely new open-source cross-platform language "Rust". Rust breaks down these barriers by eliminating the old pitfalls and providing a friendly, polished set of tools to help you along the way. Programmers who need lower-level control can do so with Rust, without taking on the risk of crashes or security holes. the language is designed to guide you naturally towards reliable code that is efficient in terms of speed and memory usage.

From Rust website (https://www.rust-lang.org)

Rust is a systems programming language that runs blazingly fast, prevents segfaults, and guarantees thread safety

Key features 
  • zero-cost abstractions
  • move semantics
  • guaranteed memory safety
  • threads without data races
  • type inference
  • minimal runtime
  • efficient C bindings

Let us walk through the few highlights

Variable Mutability

fn main() {
    let x = 5;
    println!("The value of x is: {}", x);
    x = 6;
    println!("The value of x is: {}", x);
}

See the above program and assume if it is written in C/C++. We can say this is a valid program and outputs 5 and 6 on the console. 

but if we write into rust and compile, check what happens,

error[E0384]: cannot assign twice to immutable variable `x`
 --> src/main.rs:4:5
  |
2 |     let x = 5;
  |         - first assignment to `x`
3 |     println!("The value of x is: {}", x);
4 |     x = 6;
  |     ^^^^^ cannot assign twice to immutable variable

By default Rust variables are immutable. This way Rust gives you the advantage of the safety and easy concurrency. However, you still have the option to make your variables mutable.

Rust has the mut keyword to make a variable mutable.

fn main() {
    let mut x = 5;
    println!("The value of x is: {}", x);
    x = 6;
    println!("The value of x is: {}", x);
}



If we compile now


$ cargo run
   Compiling variables v0.1.0 (file:///projects/variables)
    Finished dev [unoptimized + debuginfo] target(s) in 0.30 secs
     Running `target/debug/variables`
The value of x is: 5
The value of x is: 6

Note* mut and constant are not same. a constant variable always refers to a constant expression. It can not have an expression that has variables and can compute different values at runtime.


Ownership

Each value in Rust has a variable that’s called its owner.

fn main() {
    let s = String::from("hello");  // s comes into scope
    takes_ownership(s);             // s's value moves into the function 
println!("{}", some_string);    // It will not compile because s is no longer valid here
}

fn takes_ownership(some_string: String) { // some_string comes into scope
    println!("{}", some_string);
} // Here, some_string goes out of scope and `drop` is called. The backing memory is freed.


There can only be one owner at a time of a value.

let s1 = String::from("hello");
let s2 = s1;
println!("{}, world!", s1);

Above code compiles to errors

error[E0382]: use of moved value: `s1`
 --> src/main.rs:5:28
  |
3 |     let s2 = s1;
  |         -- value moved here
4 |
5 |     println!("{}, world!", s1);
  |                            ^^ value used here after move
  |
  = note: move occurs because `s1` has type `std::string::String`, which does
  not implement the `Copy` trait


When the owner goes out of scope, the value will be destroyed.

{
    let s = String::from("hello"); // s is valid from this point forward
    // do stuff with s
} // this scope is now over, and s is no longer valid




References and borrowing

Rust provides a way to use the value after passing to function, that is via reference (&). When we assign a value by reference it does not transfer the ownership, it just shares the reference to that object.

fn main() {
    let s1 = String::from("hello");
    let len = calculate_length(&s1);
    println!("The length of '{}' is {}.", s1, len);
}

fn calculate_length(s: &String) -> usize {
    s.len()
}

Above program compiles and run without any issue. As s1 is passed as a reference to calculate_length() function, this function does not try to drop s1 at the completion of the function.

More details: https://doc.rust-lang.org/book/2018-edition/ch04-02-references-and-borrowing.html#references-and-borrowing

Ahh! It will be an injustice to the book that I read and trying to explain the Rust language concepts.
This book has everything to start with. I would strongly recommend this book to any beginner.

At last, I would say Rust-lang is a fantastic language along with its cool toolchain that makes system programming awesome without having fear of seg-fault and memory leak.


References:
https://www.rust-lang.org/en-US/
https://doc.rust-lang.org/book/2018-edition/foreword.html
https://www.youtube.com/watch?v=_jMSrMex6R0














Total Pageviews