Creating Your First Rust Program

Let's create the first Rust program.

Creating a program that greets the user with “Hello, World” is a very popular way to test a new programming language.

When we start a project with cargo new, Rust creates “Hello, world!” for us. It also creates the necessary meta-data for Cargo to run our program.

Cargo Meta-data

We’ll open the Cargo.toml file created in our hello project:

Terminal 1
Terminal
Loading...

This file describes our program and how to build it. It uses the TOML format (Tom’s Obvious, Minimal Language) and divides crate information into sections. The [package] section describes our crate; if we publish our crate, if we publish our crate, this information will be used to describe it to potential users. It can be extended to include a lot of information about our project.

Cargo has created everything we need to run “Hello, world”, so we don’t have to edit the Cargo.toml file if we don’t want to. The default entries are:

  • name: : This is the name of your program. In this case, it’s “hello_world.” It defaults to the project name we provided when we called cargo new. When we compile our program, the name will be used as the name of our program. On Windows, hello becomes hello.exe. On UNIX-derived systems, it’ll be named hello.

  • version: This is the version of our project. Cargo will start at 0.1.0. We only need to update the version number when we publish a new version of our crate. Otherwise, we may update the version number when we feel it’s helpful to indicate that significant progress has been made. You’ll learn about Rust semantic versioning in Package Management with Cargo. For now, stick to version 0.x.y. We can go above 10 on each number, so 0.10.0 is fine.

  • authors: This is an optional list, denoted by the square braces. It may contain a comma-separated list of author names in quotation marks. If you have git setup, it automatically pulls your name and email address from there.

  • edition: This is the major edition of Rust used by the project. It will always default to the current edition. Editions are allowed to make substantial changes to Rust syntax and may break older programs. Specifying the edition tells the Rust compiler which set of syntax rules it may use.

With the meta-data in place, it’s time to look at the main program source code.

Hello World

We’ll open the src/main.rs file from our hello project using cat main.rs. Cargo has written just enough source code to display “Hello, world” on the terminal.

Terminal 1
Terminal
Loading...

Let’s work through the program, one line at a time:

fn main() {
println!("Hello World!");
}
  1. Line 1: main is a special function, marked as the program’s entry point. The syntax of the main function is defined as follows:
  1. Line 2: println! macro and string literal. See the section below, Printing text, for a detailed explanation.

Rust uses many curly brackets, ({..}). These denote scopes. A scope represents a block of code that runs together. Variables created inside a scope; they don’t leak out and are cleaned up automatically when the scope exits. In this case, printing “Hello, World” happens inside the main function’s scope.

The main function is special. It acts as the entry point for our Rust program. It doesn’t matter what order we put our functions in, main always runs first.

Printing text

The body of the main function contains the line:

println!("Hello, world!");

The exclamation mark (!) marks a macro. Rust’s macro system is very powerful and allows for syntax that wouldn’t work with regular functions. That can make macros surprising, so Rust warns us that a call is a macro by using an exclamation mark in the macro’s name. println! is a very flexible macro, offering many formatting features. In this case, we don’t need the extended syntax options; we just want to print some text.

The phrase, "Hello, world!”, is a string literal. It’s “literal” because it’s literally the text we typed into the quotation marks, stored in the program. We can put any text into the string, instead of the default “Hello, world!”. It supports Unicode. “Привет, мир” or “ こんにちは世界” are valid string literals that we can print. It even works with emojis.

Author’s Note: Being able to use symbols is great, but be careful to not overdo it. I once worked on a project that used beautiful math symbols for everything. It was lovely to read; let θ = π * Δ is a natural expression of the underlying math. When it came time to actually edit the code, changes to it became really tricky because my keyboard didn’t have buttons for most of the symbols. Rust limits our use of symbols for variable and function names for this reason.