Mike’s Newsletter

Share this post

Rust Programming Fundamentals

www.miketimashov.com

Rust Programming Fundamentals

Development.

Mike Timashov
Jul 9, 2021
3
Share this post

Rust Programming Fundamentals

www.miketimashov.com

I think it was your deliberate decision to choose Rust. It’s not so popular programming language as JavaScript, or PHP, or Java, or whatever else. But you chose Rust, and I respect your decision.

I can tell you why I started to learn Rust. I decided to develop a decentralized product on the Solana blockchain. The only solution for Solana is Rust. You can actually use C there, but it’s not recommended. So I decided to start learning Rust and I am very happy with it. I want to tell you more about Rust Programming Fundamentals. It took much time for me to find and structurize this info, so if it can help anyone - I would be satisfied.

Cargo

Cargo is a package manager, build system, test runner, docs generator, etc. It’s like all of the good parts of npm, pip, bundler, and make.

To create a new project, just run:

cargo new hello

To run the project, just run:

cargo run

And to make a release build, run:

cargo run --release

Variables in Rust

To declare a variable, you use "let"

let bunnies = 10;

Or you can use a tuple if you want to declare multiple variables at once.

let (bunnies, carrots) = (10, 50);

Rust has immutable variables by default. I think it’s not actually comfortable to use, but who cares. They tell that it’s for "Safety, Concurrency, and Speed".

To declare a mutable variable, you should use "let mut".

let mut bunnies = 10;
bunnies = 20;

Also, you can use constants in Rust. The convention is to use all uppercase words separated with underscores in constants. The type annotation is required. And value must be a constant expression that can be determined at compile time.

const BEST_LANGUAGE_IN_THE_WORLD: &str = "rust";

Memory Safety

Rust guarantees memory safety at compile time. As a part of that, variables must be initiated before you use them.

fn main() {
  let x: i32;
  println!("{}", x); // Error!
}

This code will not even compile!

Functions in Rust

fn sum(a: i32, b: i32) -> i32 {
  a+b
}

This works fine. If you don’t add the semicolon to the last expression in a block, then it will be returned as the value of the block. This is called the tail expression.

In other words…

{ return true; }

and

{ true } 

are the same.

Scalar Types

Integer types
Unsigned: u8, u16, u32, u64, u128, usize
Signed: i8, i16, i32, i64, i128, isize

In integer types, underscores are ignored when you define the value.
For example, 1000000 and 1_000_000 are the same.

Floating Point types: f32, f64. f64 is the default, but it’s slower than f32.

let x: u16 = 5;
let y: f32 = 3.14;

Booleans are true or false. BOOLEANS ARE NOT INTEGERS. So don’t try to compare them.

Character type. It’s always 4 bytes. Character literals use single quotes. And characters are useless in Rust. Character is not a part of the string.

let my_letter = 'a';

Compound types

Tuple

let info: (u8, f64, i32) = (1, 3.3, 999);

To access members of a tuple you can use dots syntax.

let jets = info.0;
let fuel = info.1;
let ammo = info.2;

Or get them all at once

let (jets, fuel, ammo) = info;

Array

let buf: [u8; 3] = [1, 2, 3]; // specify values

or

let buf: [u8; 3] = [1, 3]; // specify the value and the count

Control flow

if num == 5 {
  msg = "five";
} else if num == 4 {
  msg = "four";
} else {
  msg = "other";
}

And in Rust, we can change this code this way

msg = if num == 5 {
  "five" 
} else if num == 4 {
  "four" 
} else {
  "other"
};

How to break out of a nested loop? Easy!

‘loop1: loop {
  loop {
    loop {
      break 'loop1;
    }
  }
}

while loop is exactly similar.

while should_end_loop() {
  // do something
}

And we can write it like this:

loop {
  if !should_end_loop() { break; }
  // do something
}

I prefer "while" loop, but it’s for you to decide what to use.

One more thing here…

"For" loop can take a pattern:

let array = [(1, 2), (3, 4)];
for (x, y) in array.iter() {
  // do something with x and y
}

Strings

There are at least 6 types of strings in the Rust std library. But we mostly care about 2 of them.

The first is str. You will probably see it as &str.

let msg = "Hello World";

The second one is String. The data in str can not be modified. But the data in a String, can be modified.

let msg: String = "Hello World".to_string();

or

let msg: String = String::from("Hello World");

To access the vector of the UTF-8 bytes of a String, you can use

word.bytes();

To access chars, use

word.chars();

Ownership

Ownership in Rust is amazing. It makes Rust so different from other programming languages. And it makes those crazy safety guarantees possible.

It has 3 rules of ownership:

Rule #1. Each value has an owner.
Rule #2. Only one owner of a value.
Rule #3. Value gets dropped if its owner goes out of scope.

let s1 = String::from("abc");
let s2 = s1; // it's not a copy! value is moved.

println!("{}", s1); // Compiler Error!
Reference & Borrowing
let mut s1 = String::from("abc");
do_something(&mut s1); // it borrows the reference to the value

fn do_something(s: &mut String) {
  s.insert_str(0, "Hello, ");
}

Structs (Classes in Rust)

Struct in Rust could have variables, methods, and associated functions.

struct User {
  name: String,
  email: String,
}

You can do implementation inside structs.

impl User {
  fn new(name: String, email: String) -> Self {
    Self {
      name: name,
      email: email,
    }
  }
}

let user = User::new(String::from("Mike Timashov"), String::from("info@miketimashov.com"));

Inheritance in Rust

It’s going to be a rather short block because there is no inheritance in Rust! So is Rust Object-Oriented language? Good question.

But don’t be in a hurry to stop learning Rust. Continue reading.

Traits (Interfaces in Rust)

Traits in Rust are similar to Interfaces in other languages.

Let’s create a trait.

struct User {
  name: String,
  email: String,
}

trait Move {
  fn start_moving(&self) -> bool;
}

impl Move for User {
  fn start_moving(&self) -> bool {
    true
  }
}

Each method of a trait should be implemented.

Collections

Vector

It’s the most commonly used collection.

let mut v: Vec<i32> = Vec::new();
v.push(2);
v.push(4);
v.push(6);
let x = v.pop(); // x is 6
println!("{}", v[1]); // prints "4"

You can also create a vector much more ergonomic, like this:

let mut v = vec![2, 4, 6];

Vectors have a ton of methods.

HashMap<K, V>

In other languages, you can call it a dictionary.

let mut h: HashMap<u8, bool> = HashMap::new();
h.insert(2, true);
h.insert(7, false);

You must specify a type of Key and a type of Value.

There are a bunch of other collections: VecDeque, HashSet, LinkedList, BinaryHeap, BTreeMap, BTreeSet. You can read about them in Rust docs. I use them rarely, so I don’t want to waste time here to describe each of them.

Enums in Rust

Enums in Rust are really powerful!

enum Color {
  Red,
  Green,
  Blue,
}
let color = Color::Red;

But the most power from enums in Rust comes from associated data and methods with the variants.

enum SomeItem {
  Empty,
  Ammo(u8),
  Things(String, u32),
  Location {x: i32, y: i32},
}
use SomeItem::*;
let item = Empty;
let place = Place {x: 0, y: 0};

Isn’t this amazing?

Even better, you can implement methods with an enum.

impl SomeItem {
  fn display(&self) {}
}

And you can use enums with generics.

enum Option<T> {
  Some(T),
  None,
}

Closures in Rust

I guess you already know what closures are. I will just show you a few examples of how to use them in Rust.

let add = |x, y| { x + y }
add(1, 2); // returns 3

And another example:

let s = "Hello World".to_string();
let f = move || {
  ptintln!("{}", s);
};
f(); // prints Hello World

Threads in Rust

Here is a fully functional, but empty example of threads in Rust.

use std::thread;
fn main() {
  let handle = thread::spawn(move || {
    // do stuff in a child thread
  });

  // do stuff simultaneously in the main thread

  // wait until thread has exited
  handle.join().unweap();
}

Final Words

What do you think about this article? Should I write more about my experience with Rust, other programming languages, different platforms, my blockchain experience, etc?

Please write your comments and subscribe to my newsletter.

Leave a comment

Share this post

Rust Programming Fundamentals

www.miketimashov.com
Comments
TopNewCommunity

No posts

Ready for more?

© 2023 Mike Timashov
Privacy ∙ Terms ∙ Collection notice
Start WritingGet the app
Substack is the home for great writing