DEV Community

Cover image for How to Get Started with Rust Programming
Stella Achar Oiro
Stella Achar Oiro

Posted on

1

How to Get Started with Rust Programming

Rust is a modern systems programming language designed for performance, reliability, and productivity. This guide will walk you through setting up a Rust development environment and writing your first program.

Understanding Rust

Rust is a systems programming language with unique features that set it apart from other languages:

  • Memory Safety Without Garbage Collection: Rust's ownership system prevents common memory errors at compile time.
  • Zero-Cost Abstractions: Rust provides high-level abstractions without performance penalties.
  • Concurrency Without Data Races: The compiler prevents data races in concurrent code.
  • Modern Type System: Includes pattern matching, type inference, and generics.

By the end of this article, you will have a working Rust development environment and understand the fundamentals of the language.

Prerequisites

  • A computer running Windows, macOS, or Linux
  • Basic familiarity with command-line interfaces
  • Text editor or IDE of your choice
  • Internet connection for downloading Rust

Install Rust

The first step to using Rust is installing the language and its toolchain.

  1. Open a terminal or command prompt on your system.
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Enter fullscreen mode Exit fullscreen mode

For Windows users, download and run the installer from the official Rust website.

  1. After installation, verify Rust is correctly installed.
$ rustc --version
Enter fullscreen mode Exit fullscreen mode

You should see output similar to:

rustc 1.77.0 (9a14c5a93 2024-01-18)
Enter fullscreen mode Exit fullscreen mode
  1. Restart your terminal to ensure the Rust binaries are in your PATH.

Create Your First Rust Project

Rust projects are typically managed with Cargo, Rust's build system and package manager.

Manual Project Setup

  1. Create a new project directory.
$ mkdir ~/projects
$ cd ~/projects
$ mkdir hello_world
$ cd hello_world
Enter fullscreen mode Exit fullscreen mode
  1. Create a new source file named main.rs.
$ touch main.rs
Enter fullscreen mode Exit fullscreen mode
  1. Open main.rs in your text editor and add the following code:
fn main() {
    println!("Hello, world!");
}
Enter fullscreen mode Exit fullscreen mode

This defines a main function - the entry point of every Rust program. The println! macro prints text to the console.

Using Cargo for Project Management

Alternatively, use Cargo to create and manage your project:

  1. Create a new Cargo project.
$ cargo new hello_cargo
$ cd hello_cargo
Enter fullscreen mode Exit fullscreen mode

This command creates a new directory with a proper project structure, including a Cargo.toml file for dependencies and configuration.

  1. Examine the project structure.
$ ls
Enter fullscreen mode Exit fullscreen mode

You'll see:

  • Cargo.toml - The manifest file containing metadata and dependencies
  • src/ - Directory containing your source code
  • src/main.rs - The main source file with a "Hello, world!" program

Compiling and Running Rust Programs

Manually Compiling with rustc

  1. Compile your program using the Rust compiler.
$ rustc main.rs
Enter fullscreen mode Exit fullscreen mode
  1. Run the compiled executable.
$ ./main  # On Linux/macOS
$ .\main.exe  # On Windows
Enter fullscreen mode Exit fullscreen mode

You should see the output:

Hello, world!
Enter fullscreen mode Exit fullscreen mode

Building and Running with Cargo

Cargo streamlines the build process and dependency management:

  1. Build your Cargo project.
$ cargo build
Enter fullscreen mode Exit fullscreen mode

This creates an executable in the target/debug directory.

  1. Run your project.
$ cargo run
Enter fullscreen mode Exit fullscreen mode

This command compiles and runs your program in one step.

  1. For optimized release builds:
$ cargo build --release
Enter fullscreen mode Exit fullscreen mode

Understanding Rust Syntax Fundamentals

Now that you have a working program, let's explore some basic Rust syntax.

Variables and Data Types

Rust is statically typed but offers type inference:

fn main() {
    // Variables are immutable by default
    let x = 5;

    // Use 'mut' for mutable variables
    let mut y = 10;
    y = 15;

    // Constants require type annotations
    const MAX_POINTS: u32 = 100_000;

    // Basic types
    let integer: i32 = -42;
    let unsigned: u64 = 42;
    let float: f64 = 3.14;
    let boolean: bool = true;
    let character: char = 'z';

    // String literals and String objects
    let string_slice: &str = "hello";
    let string_object: String = String::from("world");

    println!("x = {}, y = {}", x, y);
}
Enter fullscreen mode Exit fullscreen mode

Control Flow

Rust provides familiar control flow constructs:

fn main() {
    let number = 6;

    // If expressions
    if number % 4 == 0 {
        println!("number is divisible by 4");
    } else if number % 3 == 0 {
        println!("number is divisible by 3");
    } else {
        println!("number is not divisible by 4 or 3");
    }

    // Loops
    let mut counter = 0;

    // Infinite loop with break
    loop {
        counter += 1;
        if counter == 10 {
            break;
        }
    }

    // While loop
    while counter < 20 {
        counter += 1;
    }

    // For loop
    for i in 0..5 {
        println!("i = {}", i);
    }
}
Enter fullscreen mode Exit fullscreen mode

Functions

Functions are defined using the fn keyword:

fn main() {
    // Function call
    let result = add(5, 3);
    println!("5 + 3 = {}", result);

    // Function with no return value
    greet("Rust");
}

// Function with parameters and return type
fn add(a: i32, b: i32) -> i32 {
    a + b  // No semicolon means this is a return expression
}

// Function with no return value
fn greet(name: &str) {
    println!("Hello, {}!", name);
}
Enter fullscreen mode Exit fullscreen mode

Understanding Rust's Ownership System

Rust's memory safety guarantees come from its ownership system:

Ownership Rules

  1. Each value has one owner
  2. When the owner goes out of scope, the value is dropped
  3. Ownership can be transferred (moved)
fn main() {
    // String is allocated on the heap
    let s1 = String::from("hello");

    // Ownership moves to s2, s1 is no longer valid
    let s2 = s1;

    // This would cause an error:
    // println!("{}", s1);

    // Passing ownership to a function
    takes_ownership(s2);

    // s2 is no longer valid here
}

fn takes_ownership(s: String) {
    println!("{}", s);
} // s goes out of scope and is dropped
Enter fullscreen mode Exit fullscreen mode

Borrowing

Borrowing allows you to reference data without taking ownership:

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

    // Immutable borrow
    let len = calculate_length(&s);
    println!("The length of '{}' is {}.", s, len);

    // Mutable borrowing
    let mut s = String::from("hello");
    change(&mut s);
    println!("Changed string: {}", s);
}

fn calculate_length(s: &String) -> usize {
    s.len()
} // s goes out of scope, but no drop occurs because it doesn't have ownership

fn change(s: &mut String) {
    s.push_str(", world");
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

You've now set up a Rust development environment, created your first program, and explored the fundamental concepts of the language. Rust offers a unique combination of performance and safety, making it an excellent choice for systems programming, embedded development, web services, and more.

As you continue your Rust journey, explore more advanced topics like:

  • Structs and enums
  • Error handling
  • Collections
  • Traits and generics
  • Concurrency and multi-threading

Additional Resources

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

Playwright CLI Flags Tutorial

5 Playwright CLI Flags That Will Transform Your Testing Workflow

  • 0:56 --last-failed
  • 2:34 --only-changed
  • 4:27 --repeat-each
  • 5:15 --forbid-only
  • 5:51 --ui --headed --workers 1

Learn how these powerful command-line options can save you time, strengthen your test suite, and streamline your Playwright testing experience. Click on any timestamp above to jump directly to that section in the tutorial!

Watch Full Video 📹️

👋 Kindness is contagious

Explore a trove of insights in this engaging article, celebrated within our welcoming DEV Community. Developers from every background are invited to join and enhance our shared wisdom.

A genuine "thank you" can truly uplift someone’s day. Feel free to express your gratitude in the comments below!

On DEV, our collective exchange of knowledge lightens the road ahead and strengthens our community bonds. Found something valuable here? A small thank you to the author can make a big difference.

Okay