• Как работают пакеты и крейты?

    bingo347
    @bingo347
    Crazy on performance...
    Крэйт - это в первую очередь дерево модулей. Каждый крэйт содержит как минимум 1 корневой модуль (обычно это main.rs или lib.rs, но так же это могут быть модули доп бинарников, модули интеграционных тестов, модули примеров). Так же к крэйту относятся модули, которые объявили в других модулях этого крейта (ключевое слово mod).
    Помимо этого крэйт - это сущность которой оперирует компилятор rustc, крэйт является единицей компиляции, то есть в rustc на компиляцию попадает крэйт целиком (на вход подаём корневой модуль, а он уже сам бегает по всему дереву согласно объявлениям mod).

    Пакет - это сущность которой оперирует cargo. Компилятор rustc ничего не знает про пакеты. По простому пакет это папка с файлом Cargo.toml, в котором есть секция package (бывают ещё Cargo.toml объявляющие только workspace). Пакет состоит из крейтов, притом должен быть как минимум 1 крейт бинарника или библиотеки, а библиотечный крейт может быть только 1 или отсутствовать вовсе.
    Пакет - это то, что публикуется в registry (такие как crates.io).
    Так же в зависимостях мы указываем именно пакеты (но только те, что содержат крэйт-библиотеку).
    Так же именно пакеты указываются в команде cargo install, при этом будут собраны все бинарные крейты входящие в пакет, а получившиеся исполняемые файлы будут помещены .cargo/bin
    Ответ написан
    2 комментария
  • Как правильно расположить config.toml?

    bingo347
    @bingo347
    Crazy on performance...
    Cargo считывает все конфигурационные файлы начиная с папки проекта (там где файл Cargo.lock и папка target) и во всех его родительских папках, а так же в домашней папке cargo.
    https://doc.rust-lang.org/cargo/reference/config.h...
    То есть в данном примере будут работать оба этих файла.

    Я бы проверял в сторону работает ли это условие:
    cfg(all(windows, target_env="msvc"))
    Ответ написан
    1 комментарий
  • Какой сайт с задачами rust?

    vabka
    @vabka
    Токсичный шарпист
    1. Не сайт, но сборник задач: Rust koans. По сути своей - интерактивный учебник по синтаксису языка.
    (UPD: на самом деле я думал про rustlings - это официальный сборник задач, а не koans)
    2. Когда уже уверенно можешь писать код/знаком с синтаксисом - можешь попрактиковаться на leetcode и codewars.

    Ну и лучше не на сайте сидеть, а нормальный редактор на компьютер установить, который будет давать подсказки по синтаксису и API.
    Ответ написан
    Комментировать
  • Какой сайт с задачами rust?

    bingo347
    @bingo347
    Crazy on performance...
    Онлайн запускалка кода (плэйграунд): https://play.rust-lang.org
    Официальный список задач для тренировки от создателей языка: https://github.com/rust-lang/rustlings
    ну и + то что уже Василий Банников написал
    Ответ написан
    1 комментарий
  • Как сделать collect в кортеж?

    vabka
    @vabka
    Токсичный шарпист
    Кортеж имеет фиксированный размер и по тому просто так collect сделать нельзя.
    Тут тебе три варианта:
    1. Вроде в itertools есть реализации collect для небольших гомогенных кортежей.
    2. Делай collect в Vec и бери элементы из него
    3. Сделай два раза next на итераторе

    Код

    раз
    fn main() {
        let items = [1,2];
        let mut iter = items.into_iter().map(|x|5+x);
        let a = iter.next().unwrap();
        let b = iter.next().unwrap();
        println!("{a} {b}");
    }


    Два:
    fn main() {
        let items = [1,2];
        let [a,b] = items.map(|x|5+x);
        println!("{a} {b}");
    }


    Три:
    use itertools::Itertools; // 0.9.0
    
    fn main() {
        let items = [1,2];
        let (a,b) = items.iter().map(|x|5+x).next_tuple().unwrap();
        println!("{a} {b}");
    }

    Ответ написан
    4 комментария
  • Как собрать rust проект оффлайн?

    vabka
    @vabka
    Токсичный шарпист
    Добавь опцию --offline
    cargo build --offline
    Эта опция гарантирует, что при сборке cargo не полезет в интернет.

    Предварительно тебе нужно загрузить все зависимости при помощи cargo fetch или cargo vendor

    https://doc.rust-lang.org/cargo

    UPD: Раз не понял, то вот полный рецепт, как использовать cargo vendor:
    1. Создал проект через cargo init
    2. Добавил зависимость через cargo add rand
    3. Включил вендоринг через cargo vendor (с доступом в интернет)
    4. Добавил файл .cargo/config.toml с содержимым
    [source.crates-io]
    replace-with = "vendored-sources"
    
    [source.vendored-sources]
    directory = "vendor"

    Так меня попросил сделать cargo после вызова cargo vendor

    5. Пишу код...
    fn main() {
        let x: i32 = rand::random();
        println!("{}", x);
    }

    6. Собираю cargo build --release --offline (без доступа в интернет)

    Сборка успешно проходит, никаких обращений в интернет нет.

    При этом папку с проектом я могу легко перенести на другой компьютер и также собрать без интернета.
    Ответ написан
    Комментировать
  • Есть возможность локонично реализовать множественную фильтрацию в if let?

    vabka
    @vabka
    Токсичный шарпист
    В твоём случае логичнее было бы использовать метод any, если ты хочешь просто проверить, что такие элементы существуют.

    Как вариант ты можешь сделать так, если тебе нужны потом переменные poz_*:
    fn read() -> Result<(), io::Err> {
      //let vec: Vec<u8> = !vec[2, 5, 8, 10, 15, 16];
      let pos1 = self.responce.iter().position(|&el| el == 8).ok_or_else(||io::Err::new("understading message"))?;
      let pos2 = self.responce.iter().position(|&el| el == 15).ok_or_else(||io::Err::new("understading message"))?;
      let pos3 = self.responce.iter().position(|&el| el == 12).ok_or_else(||io::Err::new("understading message"))?;
      return Ok(());
    }

    Ещё можно попробовать let-else
    Ответ написан
    8 комментариев
  • Выбрать Rust или C++?

    vabka
    @vabka
    Токсичный шарпист
    Rust достаточно стабильный и популярный, чтобы начать с ним работать.
    По геймдеву - в принципе все нужные низкоуровневые библиотеки для работы с графикой там уже есть. Да и движки свои понемногу да появляются.
    Пример из тех, что сейчас активно развиваются - bevy, на нём уже можно делать не очень сложные игры, да и просто как образец он тоже интересный: во главе угла стоит модульность и ECS.
    Ответ написан
    Комментировать
  • Rust мёртв, или только развивается?

    sergey-gornostaev
    @sergey-gornostaev
    Седой и строгий
    на данное время крупных проектов использующие его (кроме дискорда) нет

    Чеееегооо? Mozilla очень активно использет Rust, активно идут обсуждения о том, чтобы переписать ядро Linux на Rust, да огромное количество как новых, так и старых проектов используют Rust. Это один из самых быстрорастущих языков.
    Ответ написан
  • Rust мёртв, или только развивается?

    mayton2019
    @mayton2019
    Bigdata Engineer
    Смотря для кого. Rust создавался как альтернатива C++ при разработке критичных к безопасности частей кода браузера Mozilla. По бенчмаркам он реально конкурирует с C++ но главное преимущество наверное в том что из него принципиально убрали возможность совершать тупые ошибки такие как использование null-pointers. Тоесть он - безопаснее чем С++. Но мне кажется что решение за использованием Rust - корпоративное а не частное.

    Надо просто мониторить появление соотв. вакансий.

    Ну а если вы - кодер бизнес-логики на Java/C# то вам Rust скорее всего не нужен.
    Ответ написан
    Комментировать
  • Как скачать файл по прямой ссылке?

    vabka
    @vabka
    Токсичный шарпист
    Хз что именно было не так (подозреваю 'add missing generic argument')
    Но вот это работает:
    use std::{fs::OpenOptions, io::Write, path::Path};
    #[tokio::main]
    async fn main() -> Result<(), Box<dyn std::error::Error>> {
        let target = "https://www.rust-lang.org/static/images/rust-logo-blk.svg";
        let response = reqwest::get(target).await?;
    
        let path = Path::new("./image.svg");
        let mut file = OpenOptions::new().create(true).write(true).open(path)?;
        let content = response.text().await?;
        file.write_all(content.as_bytes())?; // Хочу асинхронно писать в файлы. Как это можно сделать?
        Ok(())
    }

    Пример брал из документации reqwest
    Ответ написан
    1 комментарий
  • В чем причина утечки памяти в программе на rust?

    @GeraZlo Автор вопроса
    Устранил утечку переписав большую страшную функцию, в замыкании на две маленькие, вынеся всю логику за пределы замыкания.

    Было:
    impl UserRssItemsFilter for FilterByLastRequestData {
        fn filter(&self, user: i64, rep: &String, item: &RssItem) -> bool {
            let key = format!("{} {}", user, rep);
            let r = self.last_request_cache.write(|db| {
                let last_request: DateTime<Utc> = if let Some(last_request_str) = db.get(&key) {
                    DateTime::parse_from_rfc2822(&last_request_str).unwrap().into()
                } else {
                    Utc::now() - Duration::days(2)
                };
                if last_request < item.created_date {
                    db.insert(key, item.created_date.to_rfc2822());
                    true
                } else {
                    false
                }
            }).unwrap();
            self.last_request_cache.save().unwrap();
            r
        }
    }


    Стало:
    impl UserRssItemsFilter for FilterByLastRequestData {
        fn filter(&self, user: i64, rep: &String, item: &RssItem) -> bool {
            let key = format!("{} {}", user, rep);
            let last_request = match  self.last_request_cache.read(|db| {
                match db.get(&key) {
                    Some(v) => Some(DateTime::parse_from_rfc2822(v).unwrap().into()),
                    None => None
                }
            }).unwrap() {
                Some(v) => v,
                None => Utc::now() - Duration::days(2)
            };
    
            if last_request < item.created_date {
                self.last_request_cache.write(|db| {
                    db.insert(key, item.created_date.to_rfc2822());
                }).unwrap();
                self.last_request_cache.save().unwrap();
                true
            } else {
                false
            }
        }
    }
    Ответ написан
    Комментировать
  • Как сформировать аргумент данного типа?

    @mikeyuriev
    Some((&[""], ""))
    или
    None

    Зависит о того, что вам надо. Почитайте про Option.
    Ответ написан
    Комментировать
  • Существуют ли фреймворки, позволяющие писать бекенд на rust+javascript?

    bingo347
    @bingo347
    Crazy on performance...
    Смотря что Вы понимаете под rust+javascript
    Если это проект на rust со вставками на js (например для ssr), то есть несколько вариантов:
    1. Рядом работают приложение на rust и приложение на node.js, общаются по tcp/udp/unixsock/etc.
    2. Интегрировать rust приложение как нативный аддон к node.js, общение через ffi, для этого есть neon.
    3. Внедрить js движок в приложение на rust, например есть байндинг к v8 из deno или гораздо более легковесный quick-js, правда байндинг пока сильно урезанный и не факт, что станет лучше, занимается им явно человек далекий от js. Я в свободное время пилю свою safe обертку для данного движка, моя цель как раз таки запуск ssr js фреймворков в rust приложениях, но что-то рабочее будет думаю не раньше октября.
    Ответ написан
    Комментировать
  • Rust unsafe, какие есть подводные камни и как подходить к дизайну C API?

    vabka
    @vabka
    Токсичный шарпист
    Не пудри себе мозги и возьми уже готовую безопасную обёртку над raylib
    https://crates.io/crates/raylib

    А гайд по работе с unsafe - это rustonomicon

    unsafe сам по себе просто позволяет использовать сырые указатели + вызывать другие unsafe функции.

    Безопасная обётка - это когда ты при помощи типов и всяких валидаций гарантируешь корректное использование.
    Вот пример из того что выше:
    use raylib::prelude::*;
    
    fn main() {
        let (mut rl, thread) = raylib::init()
            .size(640, 480)
            .title("Hello, World")
            .build();
    
        while !rl.window_should_close() {
            let mut d = rl.begin_drawing(&thread);
    
            d.clear_background(Color::WHITE);
            d.draw_text("Hello, world!", 12, 12, 20, Color::BLACK);
        }
    }

    Если для вас это магия, то тогда нужно чуть глубже изучить Rust и посмотреть в исходники.

    На будущее: не пишите огромную портянку текста с кучей вопросов, а пишите только то что непосредственно относится к основному вопросу.
    Другие вопросы задавайте отдельно.
    Ответ написан
    Комментировать
  • Как запустить bat файл из кода Rust?

    vabka
    @vabka
    Токсичный шарпист
    std::process::Command
    Находится буквально по запросу: "rust start process"
    Ответ написан
    Комментировать
  • С чего начать изучение языка?

    Kozack
    @Kozack Автор вопроса
    Thinking about a11y
    Комментировать
  • С чего начать изучение языка?

    vabka
    @vabka
    Токсичный шарпист
    Почему не rustbook?
    Для его понимания никакой ЯП знать не нужно
    Ответ написан
    Комментировать
  • Как безболезненно перейти с Python на Rust?

    vabka
    @vabka
    Токсичный шарпист
    Как безболезненно перейти с Python на Rust?

    Учиться, учиться, учиться.
    1) Python медленный

    Питон на удивление быстрый, особенно если использовать PyPy, а сильные тормоза возникают только в особых случаях.
    2) В python нет адекватного управления памятью

    Автоматический GC - это один из самых адекватных способов управления памятью, который только придумывало человечество.
    3) В python мне приходится испльзовать кучу мегабайт библиотек (я чувствую себя тупым и бесполезным при импортировании библеотек)

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

    Зря так думаете. Python очень мощный.
    5) Python не подходит род микроконтроллеры (micropython - просто игрушка)

    Раст+МК для новичков тоже очень страшная вещь - посмотрите на вопросы от товарища eegmak, например, чтобы в этом убедиться.
    Micropython - вполне себе production ready инструмент для тех случаев, когда его хватает, и не нужно ужиматься в очень дешёвые чипы.
    6) Проблемы из-за GIL'а

    С какими именно проблемами вы столкнулись на практике?)
    Скорее всего, их можно решить и менее радикальными методами.

    ИМХО: вы услышали от кого-то что Rust-топ язык, а Python - игрушечный, а настоящие программисты используют ручное управление памятью и сами реализовывают всякие сложные алгоритмы и протоколы.
    Хотя обычно ещё пишут, что настоящие программисты пишут только на C, только в виме, и никогда не ищут ответы на русскоязычных форумах.

    Если я прав - задумайтесь ещё раз, какую именно вашу проблему может решить раст, которую не может решить Python.

    Если я вас не отговорил - берите rustbook (лучше способа не придумали ещё).

    Если хочется перейти на другой язык, не обязательно раст - посмотрите в сторону других языков со сборкой мусора - например C#, Go, или D. Их все можно использовать в том числе и на МК, с разной степенью извращений.
    Ответ написан