Rust: Getting rusty
Rust is a relatively new system programming language. This article will attempt to cover some of the basic features of Rust that are common to languages of identical paradigms. A "hello world" A Rust hello world can be as simple as, fn main ( ) { println! ( "Hello world" ) ; ...
Rust is a relatively new system programming language. This article will attempt to cover some of the basic features of Rust that are common to languages of identical paradigms.
A "hello world"
A Rust hello world can be as simple as,
fn main() { println!("Hello world"); }
Like many other languages that use def or function, Rust uses fn to indicate a function definition. The function name follows fn, then then empty parenthesis pair () indicates that the function doesn't accept any argument. The region enclosed by brace pair {} is function body, as usual. But, probably you noticed something weird in the line println!("Hello world");, there's an exclamation sign (!) following by the function name. This is one of Rust's many unique features, and interestingly this is a macro rather than a function.
Fire it up
In order to work with Rust in our local machine, we need Rust installed. This can be achieved by running a ready made script,
curl -sSf https://static.rust-lang.org/rustup.sh | sh
Although this is a one time step you will have to take, but if you're not feeling like investing that time, then you may use the online editor available here.
Remember, Rust is a compiled language, so we have to face the same painful process of compilation before running the code. Let's do that. First, create a project directory and cd into it.
$ mkdir rusty $ cd rusty
Now create a source File with rs extension (all the rust sources have any of rs, rlib, rafto extension),
touch main.rs
and insert our little hello world program in it. Save it. And, now the part we are waiting for. Let's compile it.
rustc main.rs
rustc is the rust compiler which, as usual, generates an executable (with the same name as the source, but excluding any extension). Now run the executable
./main
Basics
Rust is like a king in it's own domain. There are too much Rust specific unique features that are to be honest, overwhelming. So, let's discuss the basic features we are generally used to and has wide cross language availability.
Variable
Variables are interesting in Rust. Let's see it through. A variable can be declared like this,
let x = 777;
But, don't be deceived by it's naive look. If you try something like this,
let x = 777; x = 44;
this will fail. And, that is because variable bindings are immutable by default. In order to define a mutable variable binding we will some something like
let mut x = 777;
Since, it's a statically typed language, you may be wondering, shouldn't I declare a data type? Rust can infer data types and so far we are using the inference feature of Rust. Now, let's define the same variable but, this time, like C/C++ we'll explicitly mention the type.
let x: i32 = 777;
Here we declared x as an immutable 32-bit integer. Now let's have a quick peek to some basic (primitive) types that we may use, Signed integer: i8, i16, i32, i64 Unsigned integer: u8, u16, u32, u64 Float: f32, f64 Boolean: bool Character: char
An important thing to note here, char is by default, four bytes.
Rust has it's referencing mechanism that can be used like,
let x = 777; let y = &x;
The & here implying that y is indicating to the reference of x. It's more complicated than it appears here. In order to explain it all we'll have to cover several Rust specific concepts like Ownership, Borrowing and Lifetime. We are safe leaving those concepts untouched as long as we are not modifying the referenced variable. So, let's skip it for now.
Let's get familiar with another type which handles sequential data. Yeah, I'm talking about array. An array declaration is made like this,
let x = [666, 777, 888];
Where some basic operations like selection by index and slicing is performed by doing this,
let x = [666, 777, 888]; // Selection by index x[1] // returns second entry // Slicing let y = &x[..]; // Returns the entire array
The new operator here .. is to indicate range. We could write,
let y = &x[2..];
which would have returned an array with only the last element of x in it.
Code units
Rust's coding units are functions. Functions have following structure.
fn function_name(arg1, arg2, ...) -> return_type { }
Interesting, isn't it? Let's take a look at a function that takes an integer and returns it's square
fn square(x: i32) -> i32 { x*x }
How about some string?
fn print_merged_str(x: &str, y: &str) { println!("{}{}", x, y); }
Did you notice something? In our string example, there is no return type specified. This, is a default. Functions that doesn't return any value doesn't need the return section. Only exceptions are divergents, but they are whole different things.