• В какую сторону решать противоречие clippy needless_return против implicit-return?

    vabka
    @vabka Куратор тега Rust
    Не противоречит.
    Implicit return по умолчанию разрешен.

    Если тебе в проекте хочется везде сделать return только явный, то тогда запрети implicit return и разреши needless return
    Ответ написан
    Комментировать
  • Насколько хороша такая политика обновления библиотеки?

    Постепенно я дополняю её патчами.

    Непонятно какую схему вы планируете для разных unstable-версий. major.new_minor.patch-unstable.1, major.new_minor.patch-unstable.2. Кстати, рекомендую выбрать какой-то более привычный prerelease-идентификатор вместо unstable, например alpha и beta.

    Также рекомендую подглядеть схему версионирования у какого-нибудь популярного крейта, например actix-web. Они используют предрелизные версии перед мажорными релизами.

    Тут кстати встаёт вопрос, а так ли вам нужны предрелизы для ПАТЧ-версий библиотеки? Выглядит как чрезмерно детальное версионирование. Обычно когда публикуется патч-апдейт, и в нём обнаруживается баг, то просто выпускается новая версия с фиксом и со следующим patch-числом (т.е. была 2.5.2, потом вышла 2.5.3 с багом, для фикса которого выпустили 2.5.4).

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

    Собственно предрелизы на то и меньше релизов при операциях сравнения, что для этого и придуманы. Т.е. например:
    1.2.5 < 1.3.0-alpha.1 < 1.3.0-alpha.2 < 1.3.0-beta.1 < 1.3.0

    Чтобы пользоваться предрелизами правильно и потом не кусать локти из-за неудачно выбранной схемы, почитайте внимательно правила сравнения в спеке semver для предрелизов и подсмотрите в популярные пакеты как кто делает. Лично мы используем схему c alpha/beta плюс через точку номер предрелизного билда.

    Схема именования предрелизов должна быть устроена так, чтобы решать задачу "приближения" к релизной версии. Если обычные 3.5.7 нужно читать как "3-я версия API + 5-й набор фичей для этого API + 7-я версия патчей для этого набора фичей", то 4.0.0-beta.6 нужно читать как «вроде бы уже почти 4.0.0, но ещё непонятно сколько ещё косяков надо перепрыгнуть, чтобы добраться до 4.0.0. На глаз вроде бы уже немного осталось (beta), но это уже 6-я бета, а до неё ещё несколько альф было, поглядим сколько ещё багов нам заведут»
    Ответ написан
    2 комментария
  • Какие можно посмотреть курсы/уроки по практике на rust?

    vabka
    @vabka Куратор тега Rust
    Оставлю шутки, про "выучил раст" в стороне и пойду по порядку, тем более что судя по недавним вопросам - заявление крайне смелое.

    0. По хорошему стоит подтянуть математику, тк она помогает абстрактно мыслить, а без этого в разработке будет крайне тяжело. (Опять же по соседним вопросам - математика не дотягивает даже до 9 класса мбоу сош).
    В принципе на этом моменте тебе больше не нужно будет задавать подобные вопросы.

    1. Проверь, что ты действительно прочитал хотябы растбук и понял его.

    2. Определись с тем, что ты будешь делать.
    Смотри что тебе больше нравится в индустрии и тем, где тебе будет приемлимо заработать. Тут решишь, что тебе приятнее - крипта, фриланс, свой какой-то мини бизнес, или найм в какую-то крупную компанию.

    3. Найди библиотеки, фреймворки для этого. Читай документацию, смотри примеры, делай какой-нибудь личный проект для практики. Сделай до завершённого состояния.

    4. На этом шаге можно уже смело пытаться заработать в п2

    Всё очень абстрактно, тк сильно зависит от того, что ты сам хочешь.
    В принципе за пару лет вполне реально управиться.

    PS: в последнее время мне нравятся видосы decrusting ... от чела https://youtube.com/@jonhoo?si=9VbtXlH4dgdCrwQ-
    Три часа непрерывного разбора всех абстракций какой-то библиотеки
    Ответ написан
    Комментировать
  • Как узнать, что программа запущена в дебагере из кода?

    vabka
    @vabka Куратор тега Rust
    Для винды есть
    https://learn.microsoft.com/en-us/windows/win32/ap...
    и
    https://learn.microsoft.com/en-us/windows/win32/ap...

    Получить доступ к ним можно через крейт windows.
    раз https://microsoft.github.io/windows-docs-rs/doc/wi...

    два https://microsoft.github.io/windows-docs-rs/doc/wi...

    На линуксе есть файлик /proc/self/status
    https://stackoverflow.com/questions/3596781/how-to...

    На маке - хз, но тк там юникс, то можно предположить, что тоже есть /proc/self/status, но это уже не точно.

    + Ещё можно посмотреть на переменные окружения. Вполне вероятно, что дебаггеры оставляют там что-нибудь, но это направление пока не смотрел
    Ответ написан
    Комментировать
  • Вызов функций С++ из .h?

    bingo347
    @bingo347
    Crazy on performance...
    Скорее всего придётся сделать extern C обёртку над библиотекой и биндится уже с ней. Ну и надо понимать, что никакие абстракции плюсов вроде темплейтов, классов и т.д. в раст не протащить.

    В какой-то степени может помочь cxx, но надо понимать, что эта штука тоже не всесильна.
    Ответ написан
  • Возврат собственного типа ошибки из main с печатью сообщения об ошибке?

    bingo347
    @bingo347
    Crazy on performance...
    fn main() -> MainResultWrapper {
        MainResultWrapper(main_inner())
    }
    
    #[inline(always)]
    fn main_inner() -> Result<(), GlobalError> {
        let config = read_config_from_file()?;
        Ok(())
    }
    Ответ написан
    Комментировать
  • Элегантный способ парсинга и обработки ошибок?

    @0x0f80
    Например метод map_err. Статейка
    pub fn build_server_config(&self) -> Result<Config, ConfigError> {
        let socket_addr_v4 = self.socket_addr.parse::<SocketAddrV4>()
            .map_err(ConfigError::WrongSocketAddr)?;
        Ok(Config {
            // инициализация полей Config
        })
    }
    Ответ написан
    1 комментарий
  • Как сделать графический интерфейс для своей ОС на rust?

    AshBlade
    @AshBlade
    Просто хочу быть счастливым
    Начать можешь с этого туториала - https://os.phil-opp.com/vga-text-mode/
    В нем реализуется простой текстовый интерфейс, но как пример этого достаточно: объясняются основные концепции как буфер видео памяти, представление букв и т.д.
    Ответ написан
    Комментировать
  • Как работают пакеты и крейты?

    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 Куратор тега Rust
    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 Куратор тега Rust
    Кортеж имеет фиксированный размер и по тому просто так 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 Куратор тега Rust
    Добавь опцию --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 Куратор тега Rust
    В твоём случае логичнее было бы использовать метод 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
    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 Куратор тега Rust
    Хз что именно было не так (подозреваю '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 комментарий