Luca Nerlich A blog about Tech, Programming and Games.

Learning Rust - Part 1

Hey there! I am trying to learn rust. Follow along, try it out yourself and maybe learn a thing or two.

All other parts of this series

Earlier

Later

rust-lang

my git repo

Im working / learning on Windows 10 using CLion as well as MacOS - which is a lot handier for commandline tasks ;-)

Rust / Cargo Installation

  1. Download rust and follow the commandline instructions.
  2. Install the gnu toolchain
    • rustup install stable-gnu
  3. Set the gnu toolchain as your default
    • rustup set default-host x86_64-pc-windows-gnu

Debugging rust on Windows

The easiest solution for a working debugging environment on windows, is to install and use cygwin.

Download the main installation .exe and during the wizard, select and download/install at least the following four packages:

If you are using CLion, your settings should look similar to this: clion_cygwin_toolchain Debugging works regardless of the unsupported version warning.

To create this toolchain, click on the plus icon and select cygwin. If you have installed cygwin in its default location, CLion will autodetect all necessary settings.

Useful Commands

  1. cargo run
  2. cargo build
  3. cargo build –release

Basic Syntax

Functions and import

The main() function is rusts application entry point. mod imports the file loops.rs. loops::run() calls the run() method from the loops.rs file.

// main.rs

mod loops;

fn main() {
    loops::run();
}
// loops.rs

pub fn run() {
    let mut count = 0;

//    print until count equals 10, then break.
    loop {
        count += 1;
        println!("{}", count);

        if count == 10 {
            break;
        }
    }
}

Basic print outs

//    print to console
    println!("We are using curly braces to print variables / values other than strings. Escape curly braces via double curly brace.");

//    using {} as format placeholders similar to java LOG.xx
    println!("{} is from {}", "luca", "hamburg");

//    we can also use numbers to refer to specific given values
    println!("{0} is from {1}", "luca", "hamburg");

//    we can also name the placeholder
    println!("{name} is from {city}", name = "luca", city = "hamburg");

//    we can also parse the incoming variable to binary, hex or octal e.g
    println!("Binary: {:b}, Hex: {:x} Octal: {:o}", 1000, 1000, 1000);
//    Binary: 1111101000, Hex: 3e8 Octal: 1750

Basic var usage

//    vars are always immutable.
    let name = "Luca";
//    type inferred to &str -> string

    let immutable = "immutable";
    let mut growable = String::from("groable");

//    adding `mut` -> makes it mutable.
    let mut age = 25;
//    type inferred to i32 -> 32bit signed integer

    println!("Name: {}", name);
    println!("Age is: {}", age);

    age += 1;
    println!("And now the age is: {}", age);

    const ID: i32 = 001;
//    type manually set to i32 -> 32bit signed integer

//    Tuples
    let person: (&str, &str, i8) = ("firstname", "lastname", 25);
    println!("{} {} {}", person.0, person.1, person.2);

    println!("Printing multiple vars using the debug placeholder :? - {:?}", (name, age));

//    Conditionals
    let height = 10;

    if height >= 10 {
        println!("Height: {} is ok. You can pass.", height);
    }

Basic types

//    default type -> i32
    let integer = 1;

//    default type -> f64
    let float = 1.1;

//    manually set type -> i64
    let integer_large: i64 = 1233456789;

//    Boolean
    let is_alive = true;

    println!("Printing multiple vars using the debug placeholder :? - {:?}", (integer, float, is_alive));

//    Char
    let emoji = '\u{1F600}';
    println!("We can even print unicode emojis: {:?}", emoji);
//    '😀'    
    
//    find max sizes - signed
    println!("Max i8: {}", std::i8::MAX);
//    127
    println!("Max i16: {}", std::i16::MAX);
//    32767
    println!("Max i32: {}", std::i32::MAX);
//    2147483647
    println!("Max i64: {}", std::i64::MAX);
//    9223372036854775807
    println!("Max i128: {}", std::i128::MAX);
//    170141183460469231731687303715884105727

Unsigned integer types cannot hold negative values.

//    find max sizes - unsigned
    println!("Max u8: {}", std::u8::MAX);
//    255
    println!("Max u16: {}", std::u16::MAX);
//    65535
    println!("Max u32: {}", std::u32::MAX);
//    4294967295
    println!("Max u64: {}", std::u64::MAX);
//    18446744073709551615
    println!("Max u128: {}", std::u128::MAX);
//    340282366920938463463374607431768211455

Arrays

//    array of exactly 5 i32.
    let numbers: [i32; 5] = [1, 2, 3, 4, 5];
    println!("{:?}", numbers)
    
//    get size in memory. Pass reference via '&'.
//    i32 -> 4 bytes. *5 arrays size -> 20bytes.
    println!("Size in mem: {} bytes.", std::mem::size_of_val(&numbers));
//    Size in mem: 20 bytes.

//    slice array
    let slice_part: &[i32] = &numbers[0..2];
    println!("Slice: {:?}", slice_part);
//   Slice: [1, 2]

Vectors

    let mut numbers: Vec<i32> = vec![1, 2, 3, 4, 5];

//    reassign value
    numbers[1] = 99;

//    add on to vector
    numbers.push(6);
    numbers.push(7);

//    remove last entry from vector
    numbers.pop();

//    print entries in for loop via iterator.
    for number in numbers.iter() {
        println!("Entry: {}", number);
    }
    
//    loop and multiply values by 2.
    for entry in numbers.iter_mut() {
        *entry *= 2;
    }
    println!("Entry: {:?}", numbers);
//    Entry: [2, 198, 6, 8, 10, 12]

Loops

    let mut count = 0;

//    print until count equals 10, then break.
    loop {
        count += 1;
        println!("{}", count);

        if count == 10 {
            break;
        }
    }

Tutorials / Downloads

Thanks for reading!

luca

category

rust