syntax and data structures / Khbr

syntax and data structures / Khbr

Hello, Habre!

Rust is a language that becomes plus or minus more popular in recent years thanks to its high performance and safety. It was developed by Mozilla and the development community to provide a system programming tool that avoids many common errors related to memory management.

In the article, we will consider the basics of Rust.

Environment settings

The rust site has instructions for installing Rust on any OS. The installation process is simple and intuitive and it can be performed by any student.

After installing Rust and Cargo, make sure they work correctly. Open the terminal and use the command:

rustc --version

The team is guilty return the current version of the Rust compiler, installed on the PC.

We check the version of Cargo:

cargo --version

If both teams successfully return tool versions, then all approx.

Creating the first application in Rust

To create a new project on Rust, you can use the command cargo new hello_rust. Cargo – is a universal tool for managing dependencies in growth. The command will create a directory with the name hello_rust, which will contain the structure of the Rust project. Inside this directory is a file main.rswe will write the code in it:

According to the classics Greetings to the world:

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

After that, you can go to the terminal, go to the project directory and run the command cargo run

Rust syntax

Variables and their mutability

One of the features of Rust is this strict type system, which helps to avoid many errors at the compilation stage:

let x = 42; // Неизменяемая переменная
let mut y = 24; // Изменяемая переменная

let is used to declare variables. The first variable x immutable, meaning that once assigned the value 42, it cannot be changed. The second variable y is declared mutable, so its value can be changed.

Operators and flow control

Rust supports all basic operatorsincluding arithmetic, logical and comparison operators:

fn ariph() {
    let a = 10;
    let b = 3;
    
    let sum = a + b; // Сложение
    let difference = a - b; // Вычитание
    let product = a * b; // Умножение
    let quotient = a / b; // Деление
    let remainder = a % b; // Остаток от деления

fn logic() {
    let is_sunny = true;
    let is_warm = false;
    
    let is_good_weather = is_sunny && is_warm; // Логическое И
    let is_raining = !is_sunny; // Логическое НЕ
}

fn sravn() {
    let x = 5;
    let y = 10;
    
    let is_equal = x == y; // Равно
    let is_not_equal = x != y; // Не равно
    let is_greater = x > y; // Больше
    let is_less = x < y; // Меньше
    let is_greater_or_equal = x >= y; // Больше или равно
    let is_less_or_equal = x <= y; // Меньше или равно
}

Conditional statements: if, else if, else

fn main() {
    let age = 25;

    if age < 18 {
        println!("Вы несовершеннолетний");
    } else if age >= 18 && age < 65 {
        println!("Вы взрослый");
    } else {
        println!("Вы пенсионер");
    }
}

Loops: for, while

Loops allow us to execute certain blocks of code multiple times. There are two main types of loops in Rust: for and while:

fn main() {
    // Цикл for
    for i in 1..=5 {
        println!("Итерация {}", i);
    }

    // Цикл while
    let mut counter = 0;
    while counter < 3 {
        println!("Повторение {}", counter);
        counter += 1;
    }
}

IN for we use a range of numbers 1..=5 to execute a block of code five times. In the case of a cycle whileexecute the block of code until the value of the variable counter is less than 3 and we increase it after each iteration.

Match expressions

Match expressions allow you to compare a value with several possible options and execute the corresponding block of code:

fn main() {
    let language = "Rust";

    match language {
        "Rust" => println!("Вы выбрали Rust - отличный выбор!"),
        "Python" | "JavaScript" => println!("Тоже хорошие языки!"),
        _ => println!("Неизвестный язык программирования"),
    }
}

If the value corresponds to “Rust”, we display a message about the choice of Rust. If it matches “Python” or “JavaScript”, we print a common message. Otherwise, we use _to process all other values.

Function declarations

fn main() {
    // Вызов функции
    greet("Alice");

    // Вызов функции с возвращаемым значением
    let result = add(3, 5);
    println!("Сумма: {}", result);
}

// Объявление функции без возвращаемого значения
fn greet(name: &str) {
    println!("Привет, {}!", name);
}

// Объявление функции с возвращаемым значением
fn add(a: i32, b: i32) -> i32 {
    a + b
}

Function parameters

fn main() {
    let a = 5;
    let b = 3;
    let sum = add(a, b);
    println!("Сумма: {}", sum);
}

fn add(x: i32, y: i32) -> i32 {
    x + y
}

add takes two parameters x and ytheir values ​​are passed from the function main when calling the function add.

Function return values

The return type is specified after the function parameters and defines the data type that the function will return:

fn main() {
    let result = multiply(4, 6);
    println!("Произведение: {}", result);
}

fn multiply(a: i32, b: i32) -> i32 {
    a * b // Это выражение будет возвращено из функции
}

multiply returns the product of two numbers of type i32.

Data structures

Whole numbers

let integer: i32 = 42; // 32-битное целое число со знаком
let unsigned_integer: u64 = 100; // 64-битное целое число без знака

Floating point numbers

let float: f32 = 3.14159265359; // 32-битное число с плавающей точкой
let double: f64 = 2.71828182845; // 64-битное число с плавающей точкой (по умолчанию)

Boolean values

let is_rust_cool: bool = true; // Логическое значение true
let is_open_source: bool = false; // Логическое значение false

Characters and strings

let char_type: char="A"; // Символ
let string_type: &str = "Hello, Rust!"; // Строка (неизменяемая)

Vectors

In Rust, vectors can be created and resized as needed:

fn main() {
    // Создание вектора целых чисел
    let mut numbers: Vec<i32> = Vec::new();
    
    // Добавление элементов в вектор
    numbers.push(42);
    numbers.push(24);
    numbers.push(12);
    
    // Доступ к элементам вектора
    let first = numbers[0];
    
    // Итерация по вектору
    for num in &numbers {
        println!("Число: {}", num);
    }
    
    // Размер вектора
    let length = numbers.len();
    
    // Удаление элемента из вектора
    let removed = numbers.pop();
}

An empty vector was created numbers to store integers, added elements to it using a method pushgot access to the element of the index and went through all the elements of the vector.

arrays

fn main() {
    // Создание массива строк
    let colors: [&str; 3] = ["Red", "Green", "Blue"];
    
    // Доступ к элементам массива
    let first_color = colors[0];
    
    // Итерация по массиву
    for color in &colors {
        println!("Цвет: {}", color);
    }
    
    // Размер массива (известен на этапе компиляции)
    let length = colors.len();
}

An array was created colorscontains three lines. Rust arrays have a fixed size that is specified when declared.

Which container to choose – vector or array? The choice depends on the specific task. If you need dynamism and the ability to change the amount of data over time, then point vectors. fit well If you know the exact size of the data in advance, then arrays are a more adequate choice.

Structures

Structures are a way to combine several variables of different types into one logical unit:

// Определение структуры Point
struct Point {
    x: f64,
    y: f64,
}

fn main() {
    // Создание экземпляра структуры Point
    let origin = Point { x: 0.0, y: 0.0 };
    
    // Доступ к полям структуры
    println!("Координаты точки: ({}, {})", origin.x, origin.y);
}

Defined the structure Pointcontaining two type fields f64x and y. Then an instance of the structure was created origin and got access to the fields.

Enumeration

// Определение перечисления Animal
enum Animal {
    Dog,
    Cat,
    Bird,
}

fn main() {
    // Использование перечисления
    let pet = Animal::Dog;
    
    // Проверка значения перечисления
    match pet {
        Animal::Dog => println!("Это собачка!"),
        Animal::Cat => println!("Это котик!"),
        Animal::Bird => println!("Это птиц!"),
    }
}

The list was determined Animal, which can take on one of three values. Then a variable was created pet and with the help of match compared its value with the enumeration options.

If you need to organize data with different fields, then the choice here is structure. If you are working with variable data or determining the state of an object, enumerations will be very appropriate.


Rust also implements nice and safe memory management, I have an article on this topic: How memory management works in Rust without a garbage collector.

In general, Rust is a very good OS and is gaining popularity.

Learn more about Rust and other programming languages ​​from my friends at OTUS in hands-on online courses. The full list of courses can be found in the catalog.

Related posts