Как программирование на Rust заставляет меня по-другому смотреть на память

Что такое ржавчина

Rust — это компилируемый язык (подобно C и C++) с акцентом на параллельность и безопасность памяти, что чрезвычайно полезно в системах, где важна производительность. Но, будучи современным языком, он имеет некоторые возможности, которые делают его замечательным, как его компилятор, который всегда помогал мне, вот пример, который я видел, как он помогал мне, как будто это был результат модульного теста

пример ошибки компилятора, чтобы показать, насколько он элегантен и чрезвычайно полезен

Тесты ?

В rust по умолчанию есть тесты и работа, которая является менеджером языковых зависимостей. Сегодня я подробнее расскажу о тестах и о том, как легко их создавать и понимать. С хорошей документацией ржавчина не оставляет желать лучшего в этом пункте.

Пример кода теста, обратите внимание, что в нем есть код #[test], который показывает, какая функция может быть использована для тестирования. Она ожидает возврата true или false и на основании этого проходит. assert_eq! может принимать строку в качестве параметров, где вы можете лучше объяснить тест.

    #[test]
    fn abstract_factory_create_car() {
        let car: Box<dyn Vehicle> = factory_method::ShapeFactory::new_vehicle(&VehicleTypes::Car);
        let result: &str = car.translocate();
        assert_eq!(result, "Moved in land", "Creating a car with a type only ");
    }

    #[test]
    fn abstract_factory_create_boat() {
        let boat: Box<dyn Vehicle> = factory_method::ShapeFactory::new_vehicle(&VehicleTypes::Boat);
        let result: &str = boat.translocate();
        assert_eq!(result, "Moved in water", "Creating a boat with a type only ");
    }

    #[test]
    fn abstract_factory_create_plane() {
        let plane: Box<dyn Vehicle> = factory_method::ShapeFactory::new_vehicle(&VehicleTypes::Plane);
        let result: &str = plane.translocate();
        assert_eq!(result, "Moved in air", "Creating a plane with a type only ");
    }
Войдите в полноэкранный режим Выход из полноэкранного режима

Есть ли у вас типы?

У нас есть типы и указатели, что делает его чрезвычайно выразительным, я могу создавать свои собственные типы, как в Vehicle, но я также могу использовать типы языка, как в result, где я использую ссылку str, которая является фрагментом String, как в случае » moved in something».

Ссылка ?

Будучи языком низкого уровня, мы обладаем некоторыми возможностями и особенностью языка, что замечательно. Концепция ссылок и заимствований, эта концепция чрезвычайно интересна и элегантна для понимания. Если вы передали переменную в качестве аргумента в функцию, вы потеряли право собственности на переменную, компилятор произнесет следующее предложение, когда вы попытаетесь использовать ее снова:

Значение уже было перемещено сюда, если вы хотите передать его снова, вы можете передать его ссылку и изменить типы так, чтобы это поддерживалось

Как работать с займами?

В rust вы можете передавать в функцию вместо переменной и перемещать ее, как требует компилятор, вы можете передавать ее ссылку и работать с ней, но никогда не мутируя и не изменяя значение. Да, существует изменяемость, но вам нужно сказать, что что-то является изменяемым, используя ключевое слово mut.

Узоры?

Rust — это функционально вдохновленный язык, в нем есть неизменяемость, соответствие шаблонам и другие черты функционального языка. Тем не менее, в нем есть современные возможности объектно-ориентированного программирования, такие как traits и strucs, и очень читабельный код, когда процедурный

#[derive(Debug)]
pub struct Unique {
    pub global_const: String,
}

/// Get the singleton that is only once initialized
pub fn get_singleton() -> &'static Mutex<Unique> {
    static mut UNIQ: MaybeUninit<Mutex<Unique>> = MaybeUninit::uninit();
    static ONCE: Once = Once::new();
    ONCE.call_once(|| unsafe {
        UNIQ.as_mut_ptr().write(Mutex::new(Unique {
            global_const: "Global string".to_string(),
        }));
    });

    unsafe { &*UNIQ.as_ptr() }
}

pub fn set_singleton(value: &str, singleton_instance: &Mutex<Unique>) {
    let mut new_value = singleton_instance.lock().unwrap();
    new_value.global_const = value.to_string();
}
Войдите в полноэкранный режим Выход из полноэкранного режима

o Шаблон синглтон

use crate::creational::factory_method::VehicleTypes::{Car as CarType, Plane as PlaneType, Boat as BoatType};

pub trait Vehicle {
    fn translocate(&self) -> &str;
}

pub enum VehicleTypes {
    Car,
    Boat,
    Plane,
}

struct Car {}

impl Vehicle for Car {
    fn translocate(&self) -> &str {
        println!("Moved in land");
        "Moved in land"
    }
}


struct Boat {}

impl Vehicle for Boat {
    fn translocate(&self) -> &str {
        println!("Moved in water");
        "Moved in water"
    }
}

struct Plane {}

impl Vehicle for Plane {
    fn translocate(&self) -> &str {
        println!("Moved in air");
        "Moved in air"
    }
}

pub struct ShapeFactory;

impl ShapeFactory {
    pub fn new_vehicle(v: &VehicleTypes) -> Box<dyn Vehicle> {
        match v {
            VehicleTypes::Car => Box::new(Car {}),
            VehicleTypes::Boat => Box::new(Boat {}),
            VehicleTypes::Plane => Box::new(Plane {}),
        }
    }
}
Войдите в полноэкранный режим Выход из полноэкранного режима

Фабричный образец

Еще примеры?

Наконец, я хотел бы оставить пример кода, который я видел на leet code, где он может быть полезен, чтобы показать некоторые приятные детали lang, который даже на низком уровне работает с легкостью, как это делают языки типа java

    /// given a list of lists which of the list is the biggest sum
    /// as the result of the table!
    ///
    /// _Table_
    /// 
    ///
    /// | Values |   Sum     | Result|  Winner|
    /// |--------|-----------|-------|--------|
    /// | 1 2 3  | 1 + 2 + 3 |  6    |        |
    /// | 5 5 5  | 5 + 5 + 5 |  15   |   X    |
    /// | 3 1 4  | 3 + 1 + 4 |  8    |        |
    /// 
    pub fn biggest_sum(res_: Vec<Vec<i32>>) -> i32 {
        res_.iter()
            .map(|x| x.iter().sum())
            .max()
            .unwrap()
    }

// Teste da função acima
    #[test]
    pub fn biggest_sum_test() {
        let v1 = vec![1, 2 ,3];
        let v2 = vec![5, 5 ,5];
        let v3 = vec![3, 1 ,4];
        let big_vec = vec![v1, v2, v3,];
        let result = biggest_sum(big_vec);

        assert_eq!(result, 15, "Testing sum, should return always 15");
    }
Войдите в полноэкранный режим Выход из полноэкранного режима

Проблема кода лита

Да, функции, заканчивающиеся на ! (нет, он не говорит вслух), являются макросами, и это деталь для другого дня, но это делает меня очень счастливым. Мы можем создавать собственные макросы, представляющие сложные функции, такие как vec![1,2,3] — то же самое, что Vec::from([1,2,3]), более простой способ инициализации ссылки

Оцените статью
devanswers.ru
Добавить комментарий