A Basic Introduction to Rust
liltaco (204)

A Basic Introduction to Rust

While there is no alternative to reading The Book, I'd like to show a bit of the syntax and basics of Rust here.

Here is a Hello World program in Rust:

fn main() {
    println!("Hello, world!");

The reason it's println! and not println is because it's a macro, but macros are far too advanced to be covered here. Rust macros allow you to write code that writes code.

You can print formatted strings, for example:

fn main() {
    println!("Hello, {num}", num=5);

This will print Hello, 5.


Variables are declared using let, e.g. let x = 5;. However, don't be fooled! This is not a dynamically typed language, but the type is inferred. That means that Rust understood x should be an integer.
Normal rust variables defined with let are immutable (you can't do let x = 5; x = 6;). To make them mutable, use let mut x = 5;.
Here's a list of common types in Rust:

  • Signed integers (can be negative) - i8, i16, i32, i64.
  • Unsigned integers (can't be negative) - u8, u16, u32, u64.
  • Floating point - f32, f64.
  • char - A unicode character.
  • String - A string. &str is a string slice, which is used for efficiency in code.
  • bool, which is true and false.
  • (), which is the empty type. It's used a lot.
  • Arrays: [1, 2, 3]. Their length can't be changed.
  • Tuples: (1, true, "hi"). Their length can't be changed. Their types are written like (i32, bool, &str).
  • Vector: A variable size array. vec![1, 2, 3] or Vec::new().

Getting input

This is overcomplicated in Rust for some reason, though it's similar to how it is in Java.

use std::io;
fn main() {
    let mut input = String::new();
        .read_line(&mut guess)
        .expect("Failed to read line");

Let's explain this. The first line, use std::io, is similar to how it works in Java: while you could have written std::io::stdin(), this gives you a shortcut for the rest of your code.
.read_line(&mut guess) - giving a function &mut gives it a mutable reference, so it can change your variables.
.expect("Failed to read line") - basic Rust error handling, which prints "Failed to read line" and stops the program.

Conditionals, loops, and such


Here is an example of an if expression (I'll explain that later):

let password = "hi";
if password == "CorrectHorseBatteryStaple" {
    println!("Correct password!");
} else if password == "123" {
    println!("It's not that easy!");
} else {
    println!("Incorrect password!");

In Rust, if you don't put a semicolon on the last line, the value is returned. You can also use the usual return. Here is an example of an if expression returning a value:

let b = true;
let x = if b {
} else {
// x is 5


// prints 1 ... 99
let mut n = 0;
while n < 100 {
    n += 1;
    println!("{}", n);


Loop is like while true.

// prints 1 ... 99
let mut n = 0;
loop {
    if n >= 100 {
    n += 1;
    println!("{}", n);


For loops are very similar to Python - they only go over iterators. 0..100 is an iterator of all the numbers 0,...,99. It's similar to range(100).

// prints 1 ... 99
for n in 1..100 {
    println!("{}", n);

You can also iterate over an array or a vector:

// prints 1 2 3
let arr = [1, 2, 3];
for n in arr.iter() {
    println!("{}", n);


Here is an example of a function:

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

fn multiply(a: i32, b: i32) -> i32 {
    return a * b;

fn printInt(a: i32) -> () {
    println!("{}", a);


Probably the most important feature of Rust, this is what replaces Object Oriented Programming. Let's see an example:

struct Point {
    x: f64,
    y: f64

This is a struct with two variables, x and y. Let's put an instance of it in a variable:

let p = Point { x: 3.0, y: 4.0 };

Now, let's add some functions to it:

impl Point {
    fn new(x: f64, y: f64) -> Point {
        Point { x: x, y: y }
    fn length(&self) -> f64 {
        (self.x * self.x + self.y * self.y).sqrt()

A function that doesnt take &self is static and doesn't have access to self. We can call them like this:

let p = Point::new(3.0, 4.0);
println!("{}", p.length); // prints 5


Enums allow us to make types which can store values of many different types, or just be used as flags.
This will be more obvious with an example:

enum MouseEvent {

fn show(event: MouseEvent) {
    match event {
        MouseEvent::LeftClick => {
	    println!("Left click");
	MouseEvent::RightClick => println!("Right click"),
	MouseEvent::Move(p) => println!("Move to {x}, {y}", x=p.x, y=p.y),
	MouseEvent::Scroll(y) => println!("Scroll {}", y)

fn main() {
    show(MouseEvent::Move(Point::new(3.0, 4.0)));

There's much more to Rust than this, including:

  • Ownership.
  • Ownership!!!
  • Splitting code to multiple files (modules)
  • Cargo (using third party packages).
  • Traits.
  • Error handling.
  • Concurrency.
    I recommend reading the official book, The Rust Programming Language. It might be a bit of a difficult read, but it's the only way to really know Rust.
You are viewing a single comment. View All