Rust: новый подход к снаряду...

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 28 окт 2022, 23:35

Сборка финальной версии (Release)
Когда проект, наконец, готов к релизу, можно использовать команду cargo build --release для его компиляции с оптимизацией. Данная команда создаёт исполняемый файл в папке target/release в отличии от папки target/debug. Оптимизации делают так, что Rust код работает быстрее, но их включение увеличивает время компиляции. По этой причине есть два отдельных профиля: один для разработки, когда нужно осуществлять сборку быстро и часто, и другой, для сборки финальной программы, которую будете отдавать пользователям, которая готова к работе и будет выполняться максимально быстро. Если вы замеряете время выполнения вашего кода, убедитесь, что собрали проект с оптимизацией cargo build --release и тестируете исполняемый файл из папки target/release.
Cargo как Конвенция
В простых проектах Cargo не даёт больших преимуществ по сравнению с использованием rustc, но он проявит себя, когда ваши программы станут более сложными. Когда программы вырастают до нескольких файлов или нуждаются в зависимостях, гораздо проще позволить Cargo координировать сборку.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 30 окт 2022, 12:57

Olej писал(а):
27 окт 2022, 19:43
Здесь полный архив кодов к книге:
Архив очень здорово организовавн (но это позволяет делать ещё и организация проектов Rust) - можно зайти в любой из последовательных (по тексту книги) проектов...

Код: Выделить всё

olej@R420:~/2022/Rust/code-1st-edition/ch1/ch1-penguins$ pwd
/home/olej/2022/Rust/code-1st-edition/ch1/ch1-penguins
... и просто "по месту" выполнить cargo run:

Код: Выделить всё

olej@R420:~/2022/Rust/code-1st-edition/ch1/ch1-penguins$ time cargo run --release
   Compiling ch1-penguins v0.1.0 (/home/olej/2022/Rust/code-1st-edition/ch1/ch1-penguins)
    Finished release [optimized] target(s) in 0.44s
     Running `target/release/ch1-penguins`
Little penguin, 33cm
Yellow-eyed penguin, 65cm
Fiordland penguin, 60cm

real    0m0,520s
user    0m0,873s
sys     0m0,120s
Код каждого проекта такой магической :lol: командой будет скомпилирован + выполнен.

А когда закончите рассматривать очередной проект:

Код: Выделить всё

olej@R420:~/2022/Rust/code-1st-edition/ch1/ch1-penguins$ cargo clean
И это приведёт каталог проекта в исходное состояние.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 30 окт 2022, 17:00

Olej писал(а):
27 окт 2022, 20:24
Язык программирования Rust (перевод)
Самые ... радикальные ;-) позиции (то что сильно отличает от других языков со статической типизацие):
Переменные и понятие изменяемости
... по умолчанию переменные являются неизменяемыми. Это одна из многих подсказок, которые Rust даёт вам для написания кода таким образом, чтобы использовать преимущества безопасности и простого параллелизма, которые предлагает Rust. Однако у вас есть возможность сделать ваши переменные изменяемыми. Давайте рассмотрим, как и почему Rust поощряет неизменность, и почему иногда вы можете отказаться от этого.
... вы можете объявить новую переменную с тем же именем, что и предыдущая переменная. Rustaceans говорят, что первая переменная затенена второй, а это значит, что компилятор увидит вторую переменную, когда вы воспользуетесь именем переменной. По сути, вторая переменная затеняет первую, присваивая себе любое использование имени переменной до тех пор, пока либо она сама не будет затенена, либо область действия не закончится.

Код: Выделить всё

fn main() {
    let x = 5;
    let x = x + 1;
    {
        let x = x * 2;
        println!("The value of x in the inner scope is: {x}");
    }
    println!("The value of x is: {x}");
}
Типы данных
Тип char в Rust имеет размер четыре байта и представляет собой скалярное значение Unicode. Это значит, что он может представлять гораздо больше, чем просто ASCII. Буквы с ударением; китайские, японские и корейские иероглифы; эмодзи и пробелы нулевой ширины являются допустимыми значениями char в Rust. Скалярные значения Unicode находятся в диапазоне от U+0000 до U+D7FF и от U+E000 до U+10FFFF включительно. Однако «символ» на самом деле не является концепцией в Unicode, поэтому интуитивно может не совпадать с тем, что такое char в Rust.
Кортеж без каких-либо значений имеет специальное имя unit. Это значение и соответствующий ему тип записываются как () и представляют собой пустое значение или пустой возвращаемый тип. Выражения неявно возвращают unit, если они не возвращают никакого другого значения.
Однако массив не такой гибкий, как векторный тип. Вектор — это аналогичный тип коллекции, предоставляемый стандартной библиотекой, размер которого может увеличиваться или уменьшаться.

Код: Выделить всё

let a: [i32; 5] = [1, 2, 3, 4, 5];
Здесь i32 является типом каждого элемента массива. После точки с запятой указано число 5, показывающее, что массив содержит 5 элементов.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 30 окт 2022, 17:22

Olej писал(а):
30 окт 2022, 17:00
Самые ... радикальные ;-) позиции
Функции
Для определения функции в Rust необходимо указать fn, за которым следует имя функции и набор круглых скобок. Фигурные скобки указывают компилятору, где начинается и заканчивается тело функции.
Вызов функции - это выражение. Вызов макроса - это выражение. Новый блок области видимости, созданный с помощью фигурных скобок, представляет собой выражение, например:

Код: Выделить всё

fn main() {
    let y = {
        let x = 3;
        x + 1
    };
    println!("The value of y is: {y}");
}
Функции могут возвращать значения коду, который их вызывает. Мы не называем возвращаемые значения, но мы должны объявить их тип после стрелки ( -> ).
...
Вы можете раньше выйти из функции и вернуть значение, используя ключевое слово return и указав значение, но большинство функций неявно возвращают последнее выражение.

Код: Выделить всё

fn five() -> i32 {
    5
}

fn main() {
    let x = five();

    println!("The value of x is: {x}");
}
у функции five нет параметров и определён тип возвращаемого значения, но тело функции представляет собой одинокую 5 без точки с запятой, потому что это выражение, значение которого мы хотим вернуть.
Управляющие конструкции
Поскольку if является выражением, его можно использовать в правой части оператора let для присвоения результата переменной

Код: Выделить всё

let condition = true;
let number = if condition { 5 } else { "six" };
В Rust есть три вида циклов: loop, while и for.
...
Также может понадобиться передать из цикла результат этой операции в остальную часть кода. Для этого можно добавить возвращаемое значение после выражения break, которое используется для остановки цикла. Это значение будет возвращено из цикла, и его можно будет использовать, как показано здесь:

Код: Выделить всё

let result = loop {
        counter += 1;
        if counter == 10 {
            break counter * 2;
        }
    };
Если у вас есть циклы внутри циклов, break и continue применяются к самому внутреннему циклу в этой цепочке. При желании вы можете создать метку цикла, которую вы затем сможете использовать с break или continue для указания, что эти ключевые слова применяются к помеченному циклу, а не к самому внутреннему циклу. Метки цикла должны начинаться с одинарной кавычки.

Код: Выделить всё

'counting_up: loop {
        println!("count = {count}");
        let mut remaining = 10;
        loop {
            println!("remaining = {remaining}");
            if remaining == 9 {
                break;
            }
            if count == 2 {
                break 'counting_up;
            }
            remaining -= 1;
        }

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 30 окт 2022, 18:19

Olej писал(а):
30 окт 2022, 17:22
Самые ... радикальные ;-) позиции
Понимание Владения
Владение - это самая уникальная особенность Rust, которая имеет глубокие последствия для всего языка. Это позволяет Rust обеспечивать безопасность памяти без использования сборщика мусора, поэтому важно понимать, как работает владение.
В некоторых языках есть сборщики мусора, которые регулярно отслеживают неиспользуемую память во время работы программы; в других программист должен память явно выделять и освобождать. В Rust используется третий подход: управление памятью происходит через систему владения с набором правил, которые проверяются компилятором. При нарушении любого из правил программа не будет скомпилирована. Ни одна из особенностей владения не замедлит работу вашей программы.
Синтаксис метода
Методы похожи на функции: мы объявляем их с помощью ключевого слова fn и имени, они могут иметь параметры и возвращаемое значение, и они содержат код, запускающийся в случае вызова метода. В отличие от функций, методы определяются в контексте структуры (или перечисления, или типаж-объекта, которые мы рассмотрим в Главах 6 и 17 соответственно), и их первым параметром всегда является self, представляющий собой экземпляр структуры, на которой вызывается этот метод.

Код: Выделить всё

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
}
Это, кстати, очень напоминает Go!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 31 окт 2022, 23:18

Olej писал(а):
27 окт 2022, 20:24
Язык программирования Rust (перевод)
К этому руководству (от авторов) не так просто найти архив кодов примеров к каждой из глав, на которые они ссылаются...
Полный GIT-репозитрий книги (с текстами) - здесь: rust-lang / book .
Там внутри вы найдёте подкаталог листингов:

Код: Выделить всё

olej@R420:~/2022/Rust$ ls -l book-main/listings
итого 76
drwxr-xr-x 13 olej olej 4096 окт 29 04:04 ch02-guessing-game-tutorial
drwxr-xr-x 43 olej olej 4096 окт 29 04:04 ch03-common-programming-concepts
drwxr-xr-x 30 olej olej 4096 окт 29 04:04 ch04-understanding-ownership
drwxr-xr-x 26 olej olej 4096 окт 29 04:04 ch05-using-structs-to-structure-related-data
drwxr-xr-x 24 olej olej 4096 окт 29 04:04 ch06-enums-and-pattern-matching
drwxr-xr-x 23 olej olej 4096 окт 29 04:04 ch07-managing-growing-projects
drwxr-xr-x 31 olej olej 4096 окт 29 04:04 ch08-common-collections
drwxr-xr-x 19 olej olej 4096 окт 29 04:04 ch09-error-handling
drwxr-xr-x 38 olej olej 4096 окт 29 04:04 ch10-generic-types-traits-and-lifetimes
drwxr-xr-x 31 olej olej 4096 окт 29 04:04 ch11-writing-automated-tests
drwxr-xr-x 32 olej olej 4096 окт 29 04:04 ch12-an-io-project
drwxr-xr-x 24 olej olej 4096 окт 29 04:04 ch13-functional-features
drwxr-xr-x 16 olej olej 4096 окт 29 04:04 ch14-more-about-cargo
drwxr-xr-x 32 olej olej 4096 окт 29 04:04 ch15-smart-pointers
drwxr-xr-x 20 olej olej 4096 окт 29 04:04 ch16-fearless-concurrency
drwxr-xr-x 23 olej olej 4096 окт 29 04:04 ch17-oop
drwxr-xr-x 36 olej olej 4096 окт 29 04:04 ch18-patterns-and-matching
drwxr-xr-x 55 olej olej 4096 окт 29 04:04 ch19-advanced-features
drwxr-xr-x 32 olej olej 4096 окт 29 04:04 ch20-web-server

Код: Выделить всё

olej@R420:~/2022/Rust$ du -hs book-main/listings
12M	book-main/listings
Там, в составе архива, полные проекты подготовленные для сборки.
Как и откуда извлечь только архив кодов (без остальных материалов книги) я не знаю!

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 02 ноя 2022, 13:43

Olej писал(а):
30 окт 2022, 17:22
Самые ... радикальные ;-) позиции
Поехали дальше...
Общие коллекции
В этой главе будет рассмотрено несколько коллекций:
* Вектор (vector) - позволяет нам сохранять различное количество последовательно хранящихся значений,
* Строка (string) - это последовательность символов. Мы же упоминали тип String ранее, но в данной главе мы поговорим о нем подробнее.
* Хеш-таблица (hash map) - коллекция которая позволяет хранить перечень ассоциаций значения с ключом (перечень пар ключ:значение). Является конкретной реализацией более общей структуры данных называемой map.
Для того, чтобы узнать о других видах коллекций предоставляемых стандартной библиотекой смотрите документацию.
Module std::collections
Rust’s collections can be grouped into four major categories:
* Sequences: Vec, VecDeque, LinkedList
* Maps: HashMap, BTreeMap
* Sets: HashSet, BTreeSet
* Misc: BinaryHeap

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 03 ноя 2022, 02:11

По очень многим синтаксическим тонкостям Rust выдаёт предупреждения (по дефаултным установкам)...
Как это выглядит и как этим управлять - подробно показано здесь: UTF-8.

О том, какие установки (прагмы, опции, lints - "ворсинки", мелочёвки) в великом множестве допускает Rust - это здесь: Warn-by-default Lints
These lints are all set to the 'warn' level by default.
Это ещё одна online книга - именно по деталям компилятора Rust: What is rustc?.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 16 дек 2022, 04:06

Olej писал(а):
28 окт 2022, 17:47
А теперь точно то же самое, но ручной компиляцией кода Rust без создания проекта
Но Rust с самого начала строится как инфраструктура (с крейтами-библиотеками, загрузкой зависимостей из репозиториев и т.д.) и, похоже, компиляция консольная rustc годится только для простейших вещей...
Пробую самое элементарное приложение с регулярными выражениями:

Код: Выделить всё

extern crate regex;
use regex::Regex;

fn main() {
   let re = Regex::new(r"^\d{4}-\d{2}-\d{2}$").unwrap();
   assert!(re.is_match("2014-01-01"));
}
Получаются ошибки типа:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ rustc regex1.rs  
error[E0463]: can't find crate for `regex`
 --> regex1.rs:1:1
  |
1 | extern crate regex;
  | ^^^^^^^^^^^^^^^^^^^ can't find crate

error: aborting due to previous error

For more information about this error, try `rustc --explain E0463`.
И как пишут в обсуждениях (Is it possible to use external crates like regex without cargo?) ... проблемы зависимостей можно разрешить только использованием менеджера cargo.

Аватара пользователя
Olej
Писатель
Сообщения: 21338
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Rust: новый подход к снаряду...

Непрочитанное сообщение Olej » 16 дек 2022, 04:11

Olej писал(а):
16 дек 2022, 04:06
проблемы зависимостей можно разрешить только использованием менеджера cargo.

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo -V
cargo 1.64.0 (387270bc7 2022-09-16)

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo search regex
regex = "1.7.0"                    # An implementation of regular expressions for Rust. This implementation uses finite automata …
lazy-regex = "2.3.1"               # lazy static regular expressions checked at compile time
proc-macro-regex = "1.1.0"         # A proc macro regex library
regex-automata = "0.2.0"           # Automata construction and matching using regular expressions.
easy-regex = "0.11.7"              # Make long regular expressions like pseudocodes
readable-regex = "0.1.0-alpha1"    # Regex made for humans. Wrapper to build regexes in a verbose style.
human_regex = "0.2.3"              # A regex library for humans
regex_static = "0.1.1"             # Compile-time validated regex, with convenience functions for lazy and static regexes.
webforms = "0.2.2"                 # Provides form validation for web forms
hashtag-regex = "0.1.1"            # A simple regex matching hashtags accoding to the unicode spec: http://unicode.org/reports/tr…
... and 883 crates more (use --limit N to see more)
Или даже так:

Код: Выделить всё

olej@R420:~/2022/own.BOOKs/Localiz/regex.cod$ cargo search regex --limit 20
regex = "1.7.0"                    # An implementation of regular expressions for Rust. This implementation uses finite automata …
lazy-regex = "2.3.1"               # lazy static regular expressions checked at compile time
proc-macro-regex = "1.1.0"         # A proc macro regex library
regex-automata = "0.2.0"           # Automata construction and matching using regular expressions.
easy-regex = "0.11.7"              # Make long regular expressions like pseudocodes
readable-regex = "0.1.0-alpha1"    # Regex made for humans. Wrapper to build regexes in a verbose style.
human_regex = "0.2.3"              # A regex library for humans
regex_static = "0.1.1"             # Compile-time validated regex, with convenience functions for lazy and static regexes.
webforms = "0.2.2"                 # Provides form validation for web forms
hashtag-regex = "0.1.1"            # A simple regex matching hashtags accoding to the unicode spec: http://unicode.org/reports/tr…
safe-regex = "0.2.5"               # Safe regular expression library
pleaser = "0.5.3"                  # please, a polite regex-first sudo alternative
rand_regex = "0.15.1"              # Generates random strings and byte strings matching a regex
regex-macro = "0.2.0"              # A macro to generate a lazy regex expression
regex-syntax = "0.6.28"            # A regular expression parser.
nfa_regex = "1.0.1"                # Simple NFA regex engine for text processing.
regexm = "0.2.1"                   # A Rust macro for writing regex pattern matching.
sbnf = "0.5.1"                     # A BNF-style language for writing sublime-syntax files
serde_regex = "1.1.0"              #     A serde wrapper that (de)serializes regex as strings 
sscanf = "0.4.0"                   # A sscanf (inverse of format!()) Macro based on Regex
... and 873 crates more (use --limit N to see more)
Обращаем внимание сколько сообществом Rust наработано в области регулярных выражений.
Пока (из того что я читал) меня интересуют:
regex = "1.7.0" # An implementation of regular expressions for Rust. This implementation uses finite automata …
lazy-regex = "2.3.1" # lazy static regular expressions checked at compile time
... может ещё:
proc-macro-regex = "1.1.0" # A proc macro regex library

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 8 гостей