Back to the basics

The other day my better half approached me and asked if I could teach her how to write software. With the whole world moving towards software and related technologies, she felt she was missing out by not knowing anything about software development. (Maybe the boredom of the global pandemic had something to do with it as well... 🤔)

Taking up the challenge, we started having regular coding sessions. Starting with the most basic "Hello World" example, she's added more functionality over the past few weeks. This section of the book captures some of the lessons and accompanying examples. I hope she sticks with my lessons, so we can expand this chapter as her skills grow.

Keep in mind that this section is intended for people with 0% programming experience. If you've coded before and know what a variable is, this section is not for you; skip ahead to the classes section to go through the Rust specifics at a much faster pace.

-- This section is for you, my coding queen!

Hello World

To develop software, you need a working development environment on your PC. This consists of two components:

  1. A compiler that can convert your source code into a program that a computer can run.
  2. An editor to write your source code and help you with common tasks.

Complete the Getting Started chapter to set this up. If you do not know how to open a terminal or command prompt, start JetBrains' RustRover instead and create a new Rust project. Select "Binary (Application)" as the type. Choose "hello_world" as the project name. This will construct a standard Rust project with a single source file: main.rs and this content:

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

You can find the main.rs file in the src directory of your newly created project.

Exploring Hello World

The project has a single function: main. This is the entry point for your application. The code is executed line by line from top to bottom. The current example has only one statement: println!("Hello, world!"); As you can imagine. This prints "Hello, world!" to standard output; the screen.

Code is held together in blocks that start with a { and end with a }. So all the code between these braces belongs to the main function. A function is defined by the fn keyword. The two ( and ) define what input a function can take. In our case, there is no input to the main function.

Standard Rust binary code always has a main function. It is placed in a file called main.rs in src.

The ; marks the end of a statement. It is used by Rust to identify where a statement ends and the next statement begins. Line breaks and spaces have no special meaning in Rust. They are just used to make the code more readable.

Expanding Hello World

In this paragraph we'll introduce a single variable first_name to the Hello World example:

fn main() {
    let first_name = "Marcel";
    println!("Hello, {first_name}!");
}

A variable is used to store data in the computer's memory. Think of the computer's memory as a cabinet with drawers. A variable is a single drawer in such a cabinet. The name of the variable, in our case first_name, is like a label that you put on the drawer so that you can remember what is stored in it.

Cabinet with drawers

In Rust a variable is defined by the let statement. The line let first_name = "Marcel"; means:

  1. Label a (new) drawer in the cabinet with "first_name"
  2. Put "Marcel" in the drawer

By convention variables in Rust use snake_case. They can not have any spaces. Use the underscore _ instead of a space.

Now that we've stored my first name in memory. We use the subsequent line to print it to the screen: println!("Hello, {}!", first_name);

The two curly brackets: {} are used as placeholders for the variable that follows the comma. In our case a single variable: first_name. There are many ways to format strings. See Formatting output for more examples.

A more convenient way to print the variable is to use it inline inside the {} brackets. Like this: println!("Hello, {first_name}!");. This will print the value of the first_name variable.

We'll use this way of printing variables throughout the book.

Run the program by clicking on the play (▶️) icon in front of fn main() and selecting Run 'Run...'. This will compile the above example into machine language and run your program. You can see the output at the bottom of the screen. It looks like this:

/Users/me/.cargo/bin/cargo run --color=always --package hello_world --bin hello_world
   Compiling hello_world v0.1.0 (/Projects/hello_world)
    Finished dev [unoptimized + debuginfo] target(s) in 1.48s
     Running `target/debug/hello_world`
Hello, world!

Process finished with exit code 0

Changing variables

In the next example, we'll explore how to change the contents of a variable. In the cabinet analogy, we'll replace the contents of the drawer with something else without relabeling the drawer.

fn main() {
    let mut first_name = "Marcel";
    println!("Hello, {first_name}!");

    first_name = "Tom";
    println!("Greetings, {first_name}!");
}

In Rust, you need to specify in advance that you may want to replace the contents of the variable - the drawer - later in your program. You do this with the mut keyword. In the example above, we create the variable first_name and write "Marcel" into it, but at the same time we mark the variable as 'mutable', telling Rust that we will change the contents of first_name at some point.

On line 2, the variable first_name has the value "Marcel", and this is what we're going to print on the screen: Hello, Marcel!.

On line 4 we assign a new value to first_name. The contents of first_name will be replaced with "Tom". In essence, we've opened the first_name drawer, removed "Marcel" and replaced it with "Tom". From now on, every time you check the first_name drawer, it will contain the value "Tom".

Note that we don't use the let statement when reassigning a variable.

Now that we've replaced the first_name value, line 5 will print: Greetings, Tom!. Try this out yourself by running the program with the play (▶️) symbol in front of fn main().

By mutating existing variables, we reuse the same drawer over and over again. This saves space in memory, i.e., in the cabinet.

Exercise

Try adding a few more greetings to this program. Use a different first name for each greeting.