Rust Ramblings: Learning Rust 1

Contents: Hello World, Comments, Data Types, Functions, Conditional Statements, Loops

Apparently Rust is the future so I thought I would hop on board. This is more of a reference for myself, than a tutorial.

I believe in learning by doing, so I found some general programming exercises, and am doing some of them. These are the exercises:

Exercises:

From: https://adriann.github.io/programming_problems.html

Ex 0: Hello World

Write a hello world program

/*
 I am a multi-line comment
*/
fn main() {
    // I am a single line comment
    println!("Hello World!");
}
  • main() entry point to the program
  • fn defines a function
  • println! - print statement

Compiling and Executing

rustc hello.rs
./hello

Types:

This is not an exercise, more of a list of types. Rust has all the same basic types as C, plus a few extras. It does not require type annotation for variables, it is able to infer the type from the declaration.

Integers:

Rust supports different sizes, and types of integers, which are prefixed by i for integer, or u for unsigned integer, followed by the number of bits in size the integer is (8, 16, 32, 64, 128).

// Integers:
let x = 2;
let x1: i32 = 20;
Mutable Variables:

When we declared a variable to be mutable with the mut keyword, it means we can modify its value.

// A mutable type:
let mut a = 0;
// When something is mutable it can be modified:
a += 1;
// a = 1
Floats:

In rust there are two types of floats, f32, and f64. f64 is the default, as it is faster.

//Float
let x = 2.0; // f64 by default
let x1: f32 = 4.0;
Boolean:

Unlike C, rust has booleans (Yay?)

// Boolean
let b = true;
let b1: bool = false;
Characters:
// Character:
let c = 'a';
let d: char = 'b';
Tuples:

A tuple is a fixed size list, that allows for elements of different types to be “grouped” together.

// Tuples
let tup: (i32, i32, bool) = (2, 4, false);
//Use pattern matching to get values (destructure):
let (x, y, z) = tup;
println!("tup has bool {}", z);

//direct access:
let z = tup.2;
Arrays:

In rust arrays are fixed size lists, in which all elements have the same type. You can not add or remove elements from the list, although you can change the values of elements.

//arrays:
//fixed size, all elements must have the same type
let a = [1, 2, 3];
let b = ["1", "2", "3"];

// An array of 3 integers:
let a1: [i32; 3] = [1,2,3];

// Creating an array with all the same values:
let a2 = [1;3];
// Creates an array of 3 1's
// a2 = [1,1,1];
Strings:

There are two string types, the string literal type, and the String object type. The string literal type is a fixed size, statically allocated (stack) array-like list of UTF-8 characters. The String type is a modifiable, with built in functions such a concat, etc. it is stored on the heap.

// The String Type:
// A string literal:
let s = "hello";
// Creating a String from a string literal:
let s1 = String::from("hello");

// A mutable string:
let mut s = String::from("app");
// Use push_str() to add a literal to s:
s.push_str("le");
// s is now "apple"

// Vector -> dynamic array, later

Ex 1: Functions:

Write a function that can add two numbers

//Baby's first function
fn main() {
    let a: i32 = 20;
    let b: i32 = 5;

    // Call the function add()
    let c = add(a, b);
    //Print the result
    println!("The sum of a and b is: {}", c);
}

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

Our function add takes 2 integers as input params, and returns an integer. The line without a semi-colon is returned. We could also write this:

fn add(a: i32, b: i32) -> i32 {
    // add a and b
    let c = a + b;
    // return c
    c
}

Ex 2: Conditional Statements:

Given three side lengths of a triangle, determine what type of triangle (scalene, isosceles, equilateral) it is

fn main() {
    triangle_type(2, 3, 2);
}

fn triangle_type(a: i32, b: i32, c: i32) {
    if a == b && b == c {
        println!("This is an equilateral triangle");
    } else if a == b || b == c || a == c {
        println!("This is an isosceles triangle");
    } else {
        println!("This is a scalene triangle");
    }
}

In rust || is logical or, && is logical and. The following conditional statements are supported: if {}, else if {}, else{}.

Ex 3: Loops

Write a program that for number n, computes the sum of the numbers from 1 to n

Rust has three types of loops: for, while, loop, we wrote a function for each type:

fn main() {
    let n = 5;
    for_sum(n);
    while_sum(n);
    loop_sum(n);
}

fn for_sum(n: i32) {
    let mut sum = 0;
    // For loop:
    for i in 1..=n {
       sum += i;
    }
    println!("The sum is : {}", sum);
}

fn while_sum(n: i32) {
    let mut sum = 0;
    let mut i = 0;
    //while loop
    while i <= n {
        sum+=i;
        i+=1;
    }
    println!("The sum is : {}", sum);
}

fn loop_sum(n: i32) {
    let mut sum = 0;
    let mut i = 0;
    //loop
    loop {
        sum+=i;
        if i == n {
            break;
        }
        i+=1;
    }
    println!("The sum is : {}", sum);
}

There are many types of for loops, for a range of numbers we have:

  • for i in 1..10 {} - for loop, integer 1-10 exclusive
  • for i in 1..=10 {} - for loop, integer 1-10 inclusive
  • for arrays, and Vecs we can use the syntax for obj in list