Rust for Beginners: A Step-by-Step Guide to Learning the Language

Are you ready to step into the world of Rust programming language? Look no further, because this guide is designed to take you through the basics of Rust, step-by-step. Rust is becoming more and more popular within the software development community, and we're about to see why.

With its emphasis on safety, speed, and concurrency, Rust is making its way into various areas of software development, from system programming to game development. Luckily, learning Rust is not as daunting as it may seem, especially with Rust for Beginners: A Step-by-Step Guide to Learning the Language.

Chapter 1: What is Rust?

Before diving into the language itself, let's first understand what Rust is. Rust is a systems programming language that was developed by Mozilla in 2010, and has since then gained popularity due to its unique design – a combination of low-level control akin to C and C++, while still maintaining high-level abstractions like Java and Python. Rust emphasizes performance, reliability, and safety—all without sacrificing speed or control.

Chapter 2: Installing Rust

Before you can begin programming in Rust, you need to install the language on your machine. Luckily, Rust makes this process relatively easy. Follow the steps below to install Rust via rustup.

  1. Open up your terminal (or command prompt) and type curl https://sh.rustup.rs -sSf | sh. If curl isn’t installed on your machine, you can download it here: https://curl.haxx.se/download.html.
  2. Once the download and installation process is complete, you can verify that Rust was installed correctly by running the command rustc --version. If you see something like rustc 1.43.0 (4fb7144ed 2020-04-20), then Rust has been successfully installed on your machine.

Chapter 3: Your First Rust Program

Now that Rust is installed, it's time to write your first Rust program! In this example, we will create a simple "Hello, World!" program that prints the text to the console.

  1. Open up a text editor of your choice (e.g., VSCode, Atom, Sublime Text).
  2. Create a new file and save it with the file extension .rs (e.g., hello_world.rs).
  3. Type in the following code:
fn main() {
    println!("Hello, world!");
}
  1. Save the file and open your terminal (or command prompt).
  2. Navigate to the directory where the Rust file is saved.
  3. Type the following command to compile the code: rustc hello_world.rs.
  4. If there are no errors, you should now see an executable file named hello_world in the same directory.
  5. To run the program, simply type ./hello_world in your terminal and hit enter.

Congratulations, you have written and run your first Rust program!

Chapter 4: Basic Syntax

Rust has a different syntax compared to other programming languages, but don't worry – we'll take you through the basic syntax of Rust step-by-step.

Variables and Data Types

In Rust, you declare a variable using the let keyword. Here's an example:

let age = 30;

In this example, we declared a variable named age and initialized it with the value 30. Rust uses static typing, which means you must declare the data type of the variable before assigning a value to it.

let name: &str = "John";

In this example, we declared a variable named name of type string (a reference to a string, to be precise) and initialized it with the value "John".

Functions

Functions are a fundamental part of Rust (and any programming language!). Here's how you define a function in Rust:

fn main() {
    // code goes here
}

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

In this example, we defined a function named add_numbers that takes two parameters (a and b, both of type i32) and returns their sum (also of type i32). The keyword fn is used to denote the declaration of a function.

Control Flow

Rust offers several control flow structures that allow you to define the flow of your program. Here are three of Rust's most commonly used control flow structures:

fn main() {
    let grade = 70;

    if grade >= 70 {
        println!("You passed!");
    } else {
        println!("You failed.");
    }
}

In this example, we used an if statement to determine whether the student passed or failed.

fn main() {
    let numbers = [10, 20, 30, 40, 50];

    for number in numbers.iter() {
        println!("{}", number);
    }
}

In this example, we looped through an array of numbers using a for loop and printed each number to the console.

fn main() {
    let day = "Monday";

    match day {
        "Monday" => println!("It's Monday!"),
        "Tuesday" => println!("It's Tuesday!"),
        "Wednesday" => println!("It's Wednesday!"),
        "Thursday" => println!("It's Thursday!"),
        "Friday" => println!("It's Friday!"),
        "Saturday" => println!("It's Saturday!"),
        "Sunday" => println!("It's Sunday!"),
        _ => println!("Invalid day."),
    }
}

In this example, we used a match expression to print out the corresponding message based on the value of day.

Ownership and Borrowing

One of the most unique features of Rust is its ownership and borrowing system. Rust uses a series of ownership and borrowing rules to ensure that memory is used safely and efficiently. Let's take a closer look at how this works.

fn main() {
    let s1 = String::from("hello");
    let s2 = s1;

    println!("{}", s2);
}

In this example, we created a new String object s1 and assigned it the value "hello". We then assigned s1 to s2, effectively transferring ownership of s1 to s2. Finally, we printed the value of s2.

This is known as "moving" ownership, and it prevents the accidental use of deallocated memory once an object goes out of scope. However, what if we wanted to use s1 again after we had assigned it to s2? This is where borrowing comes into play.

fn main() {
    let s1 = String::from("hello");
    let s2 = &s1;

    println!("{}", s2);
}

In this example, we used a reference (&) to "borrow" s1 instead of transferring ownership. This allows us to use s1 again later in the program without having to worry about invalidating the reference.

Chapter 5: Creating a Simple Game in Rust

What better way to illustrate Rust's strengths than by creating a simple game? In this example, we'll create a basic game using Rust and the popular graphics library, GGEZ.

Installing GGEZ

Before we proceed with creating the game, we'll need to install GGEZ. You can do this by adding the following dependencies to your Cargo.toml file:

[dependencies]
ggez = "0.5"

Creating the Game

  1. Create a new Rust project by running cargo new my_game.
  2. Open up the Cargo.toml file and add ggez = "0.5" as a dependency.
  3. Open up the main.rs file and replace the code with the following:
use ggez::*;

struct MainState {}

impl MainState {
    fn new() -> Self {
        Self {}
    }
}

impl EventHandler for MainState {
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
        Ok(())
    }

    fn draw(&mut self, _ctx: &mut Context) -> GameResult<()> {
        Ok(())
    }
}

pub fn main() -> GameResult {
    let (mut ctx, event_loop) = ContextBuilder::new("my_game", "Cool Game Dev")
        .build()?;
    let mut main_state = MainState::new();
    event::run(&mut ctx, &mut event_loop, &mut main_state)
}

In this example, we imported GGEZ and created a MainState struct that implements EventHandler. EventHandler defines the methods that GGEZ calls during the game loop, allowing you to control the game flow.

  1. Save the file and run the game using cargo run.

Adding Graphics

In order to make our game more interesting, let's add some graphics. We'll use an image of a spaceship as our main character.

  1. Download the image of the spaceship (or use any other image of your choice).
  2. Copy the image into the assets folder in your project.
  3. Update the MainState struct as follows:
struct MainState {
    spaceship: graphics::Image,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<Self> {
        let spaceship = graphics::Image::new(ctx, "/spaceship.png")?;
        Ok(Self { spaceship })
    }
}

impl EventHandler for MainState {
    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx, [0.1, 0.2, 0.3, 1.0].into());

        let spaceship_dest = graphics::drawparam::DrawParam::new()
            .dest([100.0, 100.0]);

        graphics::draw(ctx, &self.spaceship, spaceship_dest)?;

        graphics::present(ctx)?;

        Ok(())
    }
}

In this updated MainState struct, we created a new field named spaceship of type graphics::Image. We also updated the new method to load the spaceship image from the assets folder.

We then updated the draw method to use the spaceship image and draw it on the screen using graphics::draw(). Finally, we called graphics::present() to present the drawing buffer to the screen.

  1. Save the file and run the game using cargo run.

Adding Keyboard Input

Our game looks great, but it doesn't do anything yet. Let's add some keyboard input to make the spaceship move around the screen.

  1. Update the MainState struct as follows:
struct MainState {
    spaceship: graphics::Image,
    position: graphics::Point2,
    speed: f32,
}

impl MainState {
    fn new(ctx: &mut Context) -> GameResult<Self> {
        let spaceship = graphics::Image::new(ctx, "/spaceship.png")?;
        let position = graphics::Point2::new(100.0, 100.0);
        let speed = 5.0;
        Ok(Self { spaceship, position, speed })
    }
}

impl EventHandler for MainState {
    fn update(&mut self, ctx: &mut Context) -> GameResult<()> {
        if input::keyboard::is_key_pressed(ctx, input::keyboard::KeyCode::Left) {
            self.position.x -= self.speed;
        }
        if input::keyboard::is_key_pressed(ctx, input::keyboard::KeyCode::Right) {
            self.position.x += self.speed;
        }
        if input::keyboard::is_key_pressed(ctx, input::keyboard::KeyCode::Up) {
            self.position.y -= self.speed;
        }
        if input::keyboard::is_key_pressed(ctx, input::keyboard::KeyCode::Down) {
            self.position.y += self.speed;
        }
        Ok(())
    }

    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        graphics::clear(ctx, [0.1, 0.2, 0.3, 1.0].into());

        let spaceship_dest = graphics::drawparam::DrawParam::new()
            .dest(self.position);

        graphics::draw(ctx, &self.spaceship, spaceship_dest)?;

        graphics::present(ctx)?;

        Ok(())
    }
}

In this updated MainState struct, we added two new fields: position of type graphics::Point2 to hold the position of our spaceship, and speed of type f32 to control our spaceship’s speed.

We then updated the new method to set the initial position and speed of the spaceship.

We then updated the update method to move the spaceship based on the arrow keys input. By getting the status of the keyboard with is_key_pressed, and apply the speed accordingly.

  1. Save the file and run the game using cargo run.

Conclusion

Congratulations, you've made it through Rust for Beginners: A Step-by-Step Guide to Learning the Language! We hope that this guide has provided you with a solid foundation for understanding and programming in Rust.

While there is certainly more to learn in Rust, this guide has covered the basics of Rust syntax, concepts of Ownership, and you got to create your first Rust game!

Stay tuned for more advanced topics in Rust, we trust you have already discovered that Rust is worth learning!

Editor Recommended Sites

AI and Tech News
Best Online AI Courses
Classic Writing Analysis
Tears of the Kingdom Roleplay
Developer Flashcards: Learn programming languages and cloud certifications using flashcards
Machine Learning Events: Online events for machine learning engineers, AI engineers, large language model LLM engineers
Model Shop: Buy and sell machine learning models
Jupyter App: Jupyter applications
Cloud Data Fabric - Interconnect all data sources & Cloud Data Graph Reasoning: