ch
Feedback

不要被骗子欺骗!Telemetrio 会找到并标记这些频道 👉 如果想查看标记,请订阅

Rust

Rust

前往频道在 Telegram

Полезный контент по программированию на Rust

显示更多
2 244
订阅者
+124 小时
+37 天
+630 天
吸引订阅者
10月 '26
十月 '26
+22
在0个频道中
九月 '26
+33
在0个频道中
Get PRO
八月 '26
+19
在0个频道中
Get PRO
七月 '26
+37
在0个频道中
Get PRO
六月 '26
+31
在0个频道中
Get PRO
五月 '26
+45
在0个频道中
Get PRO
四月 '26
+28
在0个频道中
Get PRO
三月 '26
+50
在0个频道中
Get PRO
二月 '26
+72
在0个频道中
Get PRO
一月 '26
+53
在0个频道中
Get PRO
十二月 '25
+45
在0个频道中
Get PRO
十一月 '25
+53
在32个频道中
Get PRO
十月 '25
+53
在0个频道中
Get PRO
九月 '25
+87
在36个频道中
Get PRO
八月 '25
+51
在0个频道中
Get PRO
七月 '25
+80
在27个频道中
Get PRO
六月 '25
+70
在20个频道中
Get PRO
五月 '25
+87
在44个频道中
Get PRO
四月 '25
+99
在38个频道中
Get PRO
三月 '25
+80
在39个频道中
Get PRO
二月 '25
+83
在32个频道中
Get PRO
一月 '25
+84
在34个频道中
Get PRO
十二月 '24
+81
在35个频道中
Get PRO
十一月 '24
+86
在33个频道中
Get PRO
十月 '24
+111
在30个频道中
Get PRO
九月 '24
+115
在29个频道中
Get PRO
八月 '24
+107
在18个频道中
Get PRO
七月 '24
+60
在0个频道中
Get PRO
六月 '24
+65
在24个频道中
Get PRO
五月 '24
+73
在19个频道中
Get PRO
四月 '24
+78
在0个频道中
Get PRO
三月 '24
+102
在21个频道中
Get PRO
二月 '24
+96
在18个频道中
Get PRO
一月 '24
+128
在24个频道中
Get PRO
十二月 '23
+94
在24个频道中
Get PRO
十一月 '23
+82
在17个频道中
Get PRO
十月 '23
+94
在18个频道中
Get PRO
九月 '23
+92
在0个频道中
Get PRO
八月 '23
+57
在0个频道中
Get PRO
七月 '23
+50
在0个频道中
Get PRO
六月 '23
+108
在0个频道中
Get PRO
五月 '23
+123
在0个频道中
Get PRO
四月 '23
+2 402
在0个频道中
日期
订阅者增长
提及
频道
26 十月+1
25 十月0
24 十月0
23 十月0
22 十月+1
21 十月+1
20 十月+2
19 十月+2
18 十月+2
17 十月+4
16 十月+1
15 十月+1
14 十月0
13 十月+1
12 十月0
11 十月0
10 十月+2
09 十月0
08 十月+1
07 十月0
06 十月+1
05 十月0
04 十月0
03 十月0
02 十月0
01 十月+2
频道帖子
⏰ Хватит дергать: Waker и паттерн пейджера Окей, Future вернула управление (сказала Poll::Pending). Но как рантайм узнает, что данные по сети пришли и пора снова вызвать poll()? Если он будет постоянно опрашивать все Future в цикле (while loop), ваш CPU улетит в космос на 100% загрузке. Здесь на сцену выходят Executor, Reactor и Waker. • Executor - это менеджер задач. Он берет Future и вызывает у нее poll(). • Reactor - это слушатель ОС (обертка над epoll в Linux, kqueue в macOS или IOCP в Windows). Он ждет событий от сетевой карты или диска. • Waker - это тот самый пейджер, который выдают в бургерной. Как это работает: 1. Future делает сетевой запрос и понимает, что данных еще нет. 2. Она регистрирует этот запрос в Reactor и отдает ему свой Waker (колбэк, в котором зашит ID этой Future). 3. Future возвращает Pending. Executor забывает про неё и идет выполнять другие задачи. 4. ...проходит время... Сетевая карта получает пакеты. ОС дергает epoll. 5. Reactor видит: "Ага, пришли данные для сокета X". Он берет Waker, привязанный к этому сокету, и вызывает waker.wake(). 6. Waker сигнализирует Executor'у: "Задача #42 готова, помести её обратно в очередь на выполнение". 7. Executor снова вызывает poll(), и стейт-машина делает следующий шаг. Никакого холостого хода CPU. Только чистая событийная архитектура. #rust #async #waker #tokio #epoll 📲 Мы в MAX 👉 @rust_lib

2
🪄 Разрушаем магию: Твоя Future - это просто enum Многие приходят в Rust из Go или Erlang и думают, что async запускает легковесный поток (горутину). Забудьте. Асинхронный Rust работает совершенно иначе - он не аллоцирует стек под каждую задачу. Когда вы пишете async fn, компилятор превращает вашу функцию в конечный автомат (State Machine). Смотрим код: async fn fetch_data() { let req = build_request(); let resp = send(req).await; // <-- Точка остановки 1 process(resp).await; // <-- Точка остановки 2 } Под капотом LLVM генерирует невидимый enum, который хранит локальные переменные между вызовами .await: // Примерно так это видит компилятор: enum FetchDataStateMachine { Start, WaitSend { req: Request }, // Храним локальные переменные WaitProcess { resp: Response }, Done, } Когда рантайм вызывает метод poll() у этой Future: 1. Выполняется кусок кода до первого .await. 2. Состояние переключается (в WaitSend). 3. Управление возвращается обратно в рантайм! (Никакого блокирования потока). Почему это круто? Такой enum весит считанные байты. Вы можете создать миллион таких Future на обычном ноутбуке, и они займут всего пару десятков мегабайт оперативки. Никакая ОС не позволит вам создать миллион настоящих потоков. #rust #async #under_the_hood #future 📲 Мы в MAX 👉 @rust_lib
610
3
🚀 Portable SIMD: Пишем один раз, работает везде В прошлом посте вы видели ужас ручных интринсиков. Представьте, что вам нужно поддерживать SSE2, AVX2, AVX-512, да еще и ARM NEON для макбуков. Это ад из cfg_if и дублирования кода. Rust сообщество решает эту проблему. Встречайте Portable SIMD (сейчас это крейт portable-simd или фича #![feature(portable_simd)] в nightly). Идея: мы используем абстрактные типы "широких" чисел, а компилятор сам мапит их на лучшие инструкции целевой платформы. Выглядит это потрясающе чисто: #![feature(portable_simd)] // Нужен nightly Rust use std::simd::{f32x8, Simd}; fn add_portable(a: &[f32], b: &[f32], out: &mut [f32]) { // Берем чанки по 8 элементов let chunks_a = a.chunks_exact(8); let chunks_b = b.chunks_exact(8); let chunks_out = out.chunks_exact_mut(8); for ((slice_a, slice_b), slice_out) in chunks_a.zip(chunks_b).zip(chunks_out) { // Превращаем слайсы в SIMD-вектора (почти бесплатно) let vec_a = f32x8::from_slice(slice_a); let vec_b = f32x8::from_slice(slice_b); // Обычный оператор "+" работает как SIMD сложение! let vec_res = vec_a + vec_b; // Записываем обратно vec_res.copy_to_slice(slice_out); } // + нужно обработать "хвост", если длина не кратна 8 } Никакого unsafe! Никаких _mm256_ugly_names! Если вы компилируете это под AVX2 - будет AVX2. Под ARM NEON - будет NEON. Это будущее высокопроизводительного Rust. Ждем стабилизации. #rust #simd #nightly #future 📲 Мы в MAX 👉 @rust_lib
837
4
🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.ru/i_odmin Все для системного администратора https://max.ru/bash_srv Bash Советы https://max.ru/sysadminof Книги для админов, полезные материалы https://max.ru/i_odmin_book Библиотека Системного Администратора https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др. https://max.ru/tipsysdmin Типичный Сисадмин https://max.ru/channel_win_sysadmin Системный Администратор Windows https://max.ru/channel_linux_admin Linux: Системный администратор https://max.ru/channel_linuxmod Linux https://max.ru/channel_i_linux Системный администратор https://max.ru/channel_devopslib DevOps, SRE, Sysadmin https://max.ru/channel_devops_star DevOps Star (Звезда Девопса) Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С https://max.ru/channel_DevLab1C 1С:Предприятие 8 Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика https://max.ru/channel_cpp_geek C++ geek Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Rust📌 https://max.ru/channel_rust_lib Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика https://max.ru/channel_java_geek Java Geek GitHub Сообщество 📌 https://max.ru/githublib Интересное из GitHub Базы данных (Data Base) 📌 https://max.ru/database_info Все про базы данных Фронтенд разработка 📌 https://max.ru/frontend_1 Подборки для frontend разработчиков Библиотеки 📌 https://max.ru/programmist_of Книги по программированию https://max.ru/proglb Библиотека программиста https://max.ru/bfbook Книги для программистов Программирование 📌 https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 Шутки программистов 📌 https://max.ru/itumor Шутки программистов Защита, взлом, безопасность 📌 https://max.ru/thehaking Канал о кибербезопасности https://max.ru/xakkep_1 Хакер Free Книги, статьи для дизайнеров 📌 https://max.ru/odesigners Статьи, книги для дизайнеров Математика 📌 https://max.ru/Pomatematike Канал по математике https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике Вакансии в IT📌 https://max.ru/progjob https://max.ru/channel_rabotait Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Городские📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП https://max.ru/channel_krasnodar_novosty Краснодар Новости https://max.ru/channel_novosibirsk_novosti Новосибирск https://max.ru/channel_samara_novosti Новости Самары https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга https://max.ru/channel_kazan_novosti Новости Казани https://max.ru/channel_omsk_novosti Новости Омска https://max.ru/channel_moskva_24 Москва 24
751
5
💀 Хардкорный режим: std::arch и интринсики Автовекторизация не сработала? Алгоритм слишком сложен для LLVM? Придется марать руки. Встречайте std::arch. Это модуль, дающий доступ к конкретным инструкциям процессора (интринсикам). Это очень unsafe. Это не портабельно (код для x86 не заработает на ARM M1). Как выглядит сложение массивов на AVX2 (x86_64): #[cfg(target_arch = "x86_64")] use std::arch::x86_64::*; // Атрибут важен! Он говорит компилятору, что внутри этой функции // можно использовать 256-битные регистры. #[target_feature(enable = "avx2")] unsafe fn add_avx2(a: &[f32], b: &[f32], out: &mut [f32]) { // Мы обязаны обрабатывать данные чанками по 8 штук. // (Опустим проверки длин и обработку "хвостов" для краткости) for i in (0..a.len()).step_by(8) { // Загружаем 8 float'ов в 256-битный регистр let vec_a = _mm256_loadu_ps(a.as_ptr().add(i)); let vec_b = _mm256_loadu_ps(b.as_ptr().add(i)); // ОДНА инструкция сложения для 8 пар чисел let vec_res = _mm256_add_ps(vec_a, vec_b); // Выгружаем обратно в память _mm256_storeu_ps(out.as_mut_ptr().add(i), vec_res); } } Главная опасность: Если вы вызовете эту функцию на старом процессоре (без AVX2), программа упадет с ошибкой "Illegal Instruction". Решение: Runtime detection. Вы должны проверять фичи процессора в рантайме. fn add_smart(a: &[f32], b: &[f32], out: &mut [f32]) { if is_x86_feature_detected!("avx2") { // Безопасно, мы проверили unsafe { add_avx2(a, b, out) }; } else { // Медленный фоллбэк для старого железа add_scalar(a, b, out); } } Это сложно, больно, но дает максимальный контроль над железом. #rust #simd #unsafe #lowlevel #intrinsics 📲 Мы в MAX 👉 @rust_lib
692
6
🏎️ SIMD для ленивых: Автовекторизация в Rust SIMD - это когда процессор одной инструкцией складывает не два числа, а сразу 4, 8 или 16. Многие думают, что SIMD это сложно и требует unsafe. Но лучший SIMD тот, который LLVM написал за вас. Допустим, у вас есть цикл: pub fn add_arrays(a: &[f32], b: &[f32], out: &mut [f32]) { // Простые смертные пишут так: for i in 0..a.len() { out[i] = a[i] + b[i]; } } Если вы скомпилируете это в релизе для x86_64, компилятор сгенерирует инструкции SSE2 (обрабатывая по 4 числа f32 за раз). Почему? Потому что SSE2 гарантированно есть на всех 64-битных процессорах Intel/AMD. Как сделать еще быстрее? Если вы знаете, что ваш код будет работать на современном железе, разрешите компилятору использовать AVX2 (по 8 чисел f32). RUSTFLAGS="-C target-cpu=native" cargo build --release Но есть нюанс: Компилятор очень осторожен. Он не применит SIMD, если: 1. Есть риск паники. Если срезы разной длины, компилятор вставит проверки границ (bounds check) внутри цикла. Это убивает векторизацию. • Лечение: Используйте итераторы (zip) или явно проверяйте длины до цикла и используйте assert!, чтобы дать хинт оптимизатору. 2. Есть риск алиасинга. Если out пересекается в памяти с a или b. • Лечение: Rust тут молодец, его правила заимствования гарантируют отсутствие мутабельного алиасинга. Всегда смотрите в ассемблер (cargo-show-asm), чтобы убедиться, что цикл развернулся в SIMD-инструкции (ищите что-то вроде vaddps вместо addss). #rust #simd #performance #llvm #autovectorization 📲 Мы в MAX 👉 @rust_lib
748
7
🚫 Убиваем if: Branchless Programming Самый быстрый if - это отсутствие if. Иногда можно заменить ветвление на арифметику. Это гарантирует отсутствие Pipeline Flush, так как поток инструкций линейный. Задача: Вернуть a, если condition true, и b, если false. С ветвлением: let result = if condition { a } else { b }; // Генерирует инструкцию перехода (JMP/JNE) -> Риск misprediction Branchless (без ветвления): В Rust bool можно скастить в u8 (true = 1, false = 0). // (a * 1) + (b * 0) = a // (a * 0) + (b * 1) = b let result = a * (condition as i32) + b * (!condition as i32); Но подождите! Современные компиляторы часто делают это сами. Они превращают простой if в инструкцию CMOV (Conditional Move). Это инструкция процессора: "Скопируй данные, если флаг выставлен". Это не ветвление, это просто копирование по условию. Как проверить? Смотрите в ассемблер (через godbolt или cargo-show-asm). Если видите cmov - поздравляю, у вас branchless код, и он будет работать быстро, даже если данные случайны. Если видите jle / jne - это прыжок. Совет: Пишите читаемый код. И только если профайлер показывает, что BPU захлебывается в горячем цикле - переписывайте на арифметику. #rust #assembly #branchless #performance 📲 Мы в MAX 👉 @rust_lib
984
8
🥶 Холодный расчет: #[cold] и likely Компилятор Rust (LLVM) очень умный, но иногда мы знаем о поведении программы больше, чем он. Мы можем подсказать ему, какая ветка кода будет выполняться чаще. 1. Атрибут #[cold] Идеально для обработки ошибок. Вы говорите компилятору: "Сюда мы будем заходить крайне редко". Компилятор сдвинет этот код в "дальний угол" бинарника, чтобы "горячий" путь шел линейно в памяти (это улучшает работу кэша инструкций и BPU). #[cold] // <-- Подсказка fn handle_fatal_error() { // Логирование, паника, сложная логика... } fn process(data: &str) { if let Err(_) = parse(data) { handle_fatal_error(); // Компилятор знает, что это маловероятно return; } // Happy path идет дальше линейно } 2. likely / unlikely (Nightly / Crates) В стабильном Rust пока нет std::intrinsics::likely, но есть крейт likely или хаки. Это прямая инструкция процессору через LLVM. // С крейтом `likely` if likely(x > 0) { // Оптимизатор будет строить код так, // будто это условие почти всегда true } Используйте #[cold] для ошибок и граничных случаев. Это стабильно, бесплатно и делает код чище. #rust #optimization #llvm #hints 📲 Мы в MAX 👉 @rust_lib
1 192
9
🔮 Ты не пройдешь: Магия предсказателя ветвлений Вы когда-нибудь задумывались, почему обработка отсортированного массива чисел происходит в разы быстрее, чем случайного, даже если логика одна и та же? Всё дело в конвейере (pipeline). Процессор выполняет инструкции не по одной, а потоком: пока одна декодируется, другая уже выполняется. Но тут появляется if (ветвление). Процессор не знает, пойдет код в then или в else, пока не вычислит условие. Но ждать он не может - конвейер встанет. Поэтому он угадывает. • Угадал? Выполнение продолжается без задержек. • Не угадал? Происходит Pipeline Flush. Процессор выбрасывает все инструкции, которые успел "набрать" по неверному пути, и начинает заново с правильного адреса. Это огромная потеря тактов (10-20 циклов CPU). Пример на Rust: // Если data отсортирован: T T T T T F F F F F (паттерн ясен) // Если data случайный: T F T T F F T F (паттерн непредсказуем) for &x in &data { if x > 128 { sum += x; } } На случайных данных BPU ошибается в 50% случаев. На сортированных почти никогда. Вывод: Чем предсказуемее ваши данные, тем быстрее работает ваш код. Иногда data.sort() перед обработкой окупается с лихвой. #rust #cpu #lowlevel #performance #branch_prediction 📲 Мы в MAX 👉 @rust_lib
1 083
10
🗝 Турбируем HashMap Стандартный std::collections::HashMap в Rust использует алгоритм хэширования SipHash. Почему? Он криптографически стоек к HashDoS атакам (когда злоумышленник подбирает ключи так, чтобы все они попадали в один бакет, превращая мапу в связный список и убивая CPU). Но SipHash медленный. Если вы решаете алгоритмические задачи, пишете геймдев или у вас внутренний сервис без внешнего доступа - вам не нужна защита от DoS. Вам нужна скорость. Используйте сторонние хэшеры. Самые популярные: 1. FxHash (rustc-hash) - используется внутри самого компилятора Rust и Firefox. Молниеносно быстрый для коротких ключей (integers). 2. AHash - современный, быстрый, использует аппаратные инструкции AES. Пример с крейтом rustc-hash: use rustc_hash::FxHashMap; // Это та же HashMap, но с быстрым хэшером let mut map: FxHashMap<u32, &str> = FxHashMap::default(); Прирост производительности на операциях вставки/поиска может достигать 2x-3x на простых ключах. Итог: • Backend наружу? Оставляем дефолтный SipHash. • GameDev / Algo / Internal Data Processing? Ставим FxHash или AHash. #rust #performance #hashmap #external_crates 📲 Мы в MAX 👉 @rust_lib
1 083
11
⚡️ Забудь про RefCell для примитивов Вам нужно изменить поле внутри неизменяемой структуры (&self). Рука тянется к RefCell? Стоп. RefCell имеет оверхед: 1. Хранит счетчик заимствований (borrow count). 2. В рантайме проверяет правила (может паниковать!). Если ваш тип реализует Copy (числа, bool, маленькие структуры) - используйте Cell. В чем магия Cell? У него нет никакого рантайм-оверхеда. Вообще. Он не проверяет заимствования. Он работает так: "Я даю тебе копию значения" (get) или "Я заменяю значение целиком" (set). Вы не можете получить ссылку (&) на содержимое Cell, поэтому правила Rust не нарушаются. use std::cell::Cell; struct Metric { count: Cell<u64>, // Zero overhead } impl Metric { fn inc(&self) { // Мы меняем значение по неизменяемой ссылке &self let current = self.count.get(); self.count.set(current + 1); } } Это атомарно? Нет. Это работает только в одном потоке. Но для однопоточного кода (или внутри thread_local) это самая быстрая мутабельность, которая только возможна. #rust #std #optimization #interior_mutability 📲 Мы в MAX 👉 @rust_lib
921
12
Создание кроссплатформенного приложения с GUI на Rust: От идеи до реальности Electron-приложения тяжелые, потребляют много па
Создание кроссплатформенного приложения с GUI на Rust: От идеи до реальности Electron-приложения тяжелые, потребляют много памяти, а на Rust можно собрать легкое, быстрое и безопасное десктоп-приложение, которое будет работать на Windows, macOS и Linux. Tauri — это фреймворк, который позволяет использовать веб-технологии (HTML/CSS/JS) для интерфейса и мощь Rust для бэкенда. Но чтобы собрать работающий продукт, а не просто «посмотреть пример», нужно понимать, как связать фронтенд с бэкендом, работать с файловой системой, делать асинхронные вызовы и правильно собирать билды. На открытом вебинаре 23 сентября в 20:00 разберём полный цикл создания кроссплатформенного GUI-приложения на Rust с использованием Tauri. Посмотрим, как организовать проект, как писать логику на Rust и подключать её к интерфейсу, как сохранять и загружать данные,безопасно работать с файловой системой и системными вызовами через новую систему разрешений (permissions) и возможностей (capabilities) в Tauri 2, а также выполнять долгие операции асинхронно. Отдельно обсудим сборку готового приложения, отладку с помощью встроенных инструментов Tauri и лучшие практики, которые помогут избежать типичных ошибок. Вебинар не для тех, кто ждёт готового шаблона «скопируй-вставь» без понимания архитектуры. Идеально подойдёт фронтенд-разработчикам, которые хотят создавать настоящие десктоп-приложения, программистам на других языках, интересующимся Rust и кроссплатформенной разработкой, а также энтузиастам, которые устали от тяжелых Electron-приложений. После вебинара вы сможете создавать функциональные десктоп-приложения на Rust с красивым интерфейсом, разрабатывать логику на бэкенде и связывать её с UI, грамотно настраивать политики безопасности доступа к ресурсам ОС, а также собирать и распространять готовое приложение пользователям. 👉 Записаться: https://vk.cc/d1KKyw Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
807
13
Почему Vec::new() это ловушка для производительности. 📈 Векторный рост: Избегаем реаллокаций Мы часто пишем: let mut vec = Vec::new(); for item in heavy_iter { vec.push(item); } Что происходит под капотом? 1. Вектор создается пустым (0 байт). 2. Первый push: аллокация на 4 элемента (условно). 3. Пятый push: места нет. • Создается новый буфер (размером x2). • Все старые элементы копируются туда. • Старый буфер освобождается. • Новый элемент записывается. Это называется Reallocation. Это дорого. Если у вас 10 миллионов элементов, вы сделаете десятки реаллокаций и скопируете гигабайты данных просто так. Решение: Если вы хотя бы примерно знаете размер - подскажите компилятору. // Идеально, если знаем точно let mut vec = Vec::with_capacity(exact_count); // Или используем итераторы, они часто сами знают свой размер let vec: Vec<_> = heavy_iter.collect(); collect() умный. Он смотрит на size_hint итератора и сразу аллоцирует нужный буфер (если итератор "честный"). Правило: Vec::new() - только если вы правда не знаете, будет ли там хоть один элемент. В остальных случаях - with_capacity. #rust #performance #vectors 📲 Мы в MAX 👉 @rust_lib
894
14
🤠 Трюк Индианы Джонса: std::mem::take Типичная ситуация: у вас есть &mut self, и вы хотите забрать поле (например, String или Vec), что-то с ним сделать, и, возможно, вернуть обратно или сохранить измененную версию. Компилятор бьет по рукам: нельзя просто так переместить (move) значение из-за мутабельной ссылки. Новички часто делают .clone(), чтобы успокоить borrow checker. Но это лишняя аллокация! Решение: std::mem::take. Оно забирает значение из ссылки, оставляя на его месте Default::default(). struct Buffer { data: Vec<u8>, } impl Buffer { fn process(&mut self) { // Мы "выкрадываем" вектор. // В self.data теперь пустой Vec (без аллокаций). let raw_data = std::mem::take(&mut self.data); // Тяжелая обработка в другом потоке/функции, // требующая владения (ownership) let processed = heavy_transform(raw_data); // Возвращаем результат self.data = processed; } } Это работает для всего, что реализует Default (Option, String, Vec). Для типов без Default есть std::mem::replace. Это zero-cost, семантически верно и намного быстрее клонирования. #rust #std #optimization #tips 📲 Мы в MAX 👉 @rust_lib
844
15
🐮 Cow: Ленивое клонирование Все знают: лишний clone() - это грех. Но иногда нам нужно вернуть строку, которая может быть изменена, а может и нет. Допустим, мы чистим инпут от спецсимволов. 1. Если спецсимволов нет - зачем аллоцировать новую строку? Можно вернуть ссылку на исходную. 2. Если есть - придется создать новую String. Здесь на сцену выходит std::borrow::Cow (Clone on Write). use std::borrow::Cow; fn sanitize(input: &str) -> Cow<str> { if input.contains('!') { // Аллокация происходит только тут Cow::Owned(input.replace('!', "?")) } else { // Тут мы просто возвращаем ссылку. Zero allocation. Cow::Borrowed(input) } } Это мощнейший инструмент для хот-пасов (hot paths), где 90% данных не требуют изменений. Не ленитесь использовать Cow там, где можно избежать лишних аллокаций. #rust #performance #std 📲 Мы в MAX 👉 @rust_lib
933
16
Владение, заимствование и ссылки в Rust: как компилятор делает ваш код безопасным В Rust одна из самых непривычных для разраб
Владение, заимствование и ссылки в Rust: как компилятор делает ваш код безопасным В Rust одна из самых непривычных для разработчиков тем — это ownership (владение) и borrowing (заимствование). Многие пытаются писать на Rust как на C++ или Python, натыкаются на компилятор, и правила borrow checker'а поначалу кажутся слишком строгими. На деле компилятор просто защищает вас от ошибок, которые в других языках приводят к падениям, утечкам памяти и гонкам данных. Но чтобы подружиться с borrow checker’ом, нужно понять логику, а не заучивать правила. На открытом вебинаре 9 сентября в 20:00 разберём фундаментальные концепции Rust, которые делают код безопасным без сборщика мусора. Поговорим о том, почему на одни и те же данные можно взять сколько угодно иммутабельных ссылок (&), но мутабельная (&mut) может быть только одна — и не одновременно с иммутабельными. Разберём, чем перемещение (move) отличается от копирования (Copy/Clone). Обсудим, что такое время жизни (lifetimes): когда его нужно указывать явно, а когда компилятор выводит его сам по правилам элизии (lifetime elision). На практических примерах посмотрим, как разбирать типичные ошибки borrow checker'а, писать функции, безопасно работающие со ссылками и слайсами, и почему правила владения и заимствования предотвращают гонки данных, обращение к освобождённой памяти и двойное освобождение. Вебинар не для тех, кто хочет просто «посмотреть синтаксис» без погружения в модель памяти. Подойдёт тем, кто уже знаком с основами языка — переменными, функциями, типами — и хочет наконец разобраться в модели памяти Rust, а также программистам с опытом в C++, Java или Python, которые хотят понять самую важную и необычную концепцию языка. 👉 Записаться: https://vk.cc/d1fh5M Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
1 041
17
🛠 Cargo Expand: Загляни под капот макросам Признайтесь, у вас бывало такое: навесили #[derive(Serialize)] или сложный макрос из sqlx, получили странную ошибку компиляции и сидите в ступоре? Макросы это круто, но это черный ящик. Чтобы превратить его в прозрачный, поставьте cargo-expand. cargo install cargo-expand Запускаем: cargo expand И видите весь тот ужас (или красоту), который генерируется до того, как код попадет к компилятору. Это маст-хэв тулза при отладке async трейтов (привет, async-trait крейт) и понимании того, как работает "магия" фреймворков типа Actix или Rocket. P.S. Только не пугайтесь, когда увидите, во что разворачивается println!. #rust #tools #cargo #macro 📲 Мы в MAX 👉 @rust_lib
829
18
👻 Сила пустоты: Zero-Sized Types (ZST) Мы часто говорим про "zero-cost abstractions", но редко задумываемся, как это выглядит в памяти. ZST - это типы, которые занимают 0 байт. Компилятор знает о них, но в рантайме они исчезают. Зачем это нужно, кроме экономии памяти? Для управления состоянием на уровне типов. Представьте, что у вас есть стейт-машина. Вместо того чтобы хранить enum State и делать проверки в рантайме: struct Socket<State> { inner: FileDesc, _marker: PhantomData<State>, // 0 байт } // ZST-маркеры struct Connected; struct Disconnected; impl Socket<Disconnected> { fn connect(self) -> Socket<Connected> { // Логика подключения... // Трансформация типа без оверхеда в памяти unsafe { std::mem::transmute(self) } } } impl Socket<Connected> { fn send(&self, data: &[u8]) { ... } } В чем профит? 1. Вы физически не можете вызвать метод send у Disconnected сокета. Код просто не скомпилируется. 2. В скомпилированном бинарнике нет никаких флагов состояния, if state == connected и прочего мусора. Метод просто вызывается. Используйте систему типов, чтобы делать некорректные состояния невыразимыми (Make invalid states unrepresentable). #rust #advanced #architecture #zst 📲 Мы в MAX 👉 @rust_lib
835
19
🚀 Подборка полезных IT каналов в Max Системное администрирование, DevOps 📌 https://max.ru/i_odmin Все для системного администратора https://max.ru/bash_srv Bash Советы https://max.ru/sysadminof Книги для админов, полезные материалы https://max.ru/i_odmin_book Библиотека Системного Администратора https://max.ru/i_devops DevOps: Пишем о Docker, Kubernetes и др. https://max.ru/tipsysdmin Типичный Сисадмин https://max.ru/channel_win_sysadmin Системный Администратор Windows https://max.ru/channel_linux_admin Linux: Системный администратор https://max.ru/channel_linuxmod Linux https://max.ru/channel_i_linux Системный администратор https://max.ru/channel_devopslib DevOps, SRE, Sysadmin https://max.ru/channel_devops_star DevOps Star (Звезда Девопса) Excel лайфхак 📌 https://t.me/Excel_lifehack Excel лайфхак Английский с нуля 🇬🇧 https://max.ru/UchuEnglish 1C разработка 📌 https://max.ru/odin1c_rus Cтатьи, курсы, советы, шаблоны кода 1С https://max.ru/channel_DevLab1C 1С:Предприятие 8 Программирование C++📌 https://max.ru/cpp_lib Библиотека C/C++ разработчика https://max.ru/channel_cpp_geek C++ geek Программирование Go📌 https://max.ru/golang_lib Библиотека Go (Golang) разработчика Программирование React📌 https://max.ru/react_lib React Программирование Rust📌 https://max.ru/channel_rust_lib Программирование Python 📌 https://max.ru/python_of Python академия. https://max.ru/BookPython Библиотека Python разработчика Java разработка 📌 https://max.ru/bookjava Библиотека Java разработчика https://max.ru/channel_java_geek Java Geek GitHub Сообщество 📌 https://max.ru/githublib Интересное из GitHub Базы данных (Data Base) 📌 https://max.ru/database_info Все про базы данных Фронтенд разработка 📌 https://max.ru/frontend_1 Подборки для frontend разработчиков Библиотеки 📌 https://max.ru/programmist_of Книги по программированию https://max.ru/proglb Библиотека программиста https://max.ru/bfbook Книги для программистов Программирование 📌 https://max.ru/bookflow Лекции, видеоуроки, доклады с IT конференций https://max.ru/itmozg Программисты, дизайнеры, новости из мира IT https://max.ru/php_lib Библиотека PHP программиста 👨🏼‍💻👩‍💻 Шутки программистов 📌 https://max.ru/itumor Шутки программистов Защита, взлом, безопасность 📌 https://max.ru/thehaking Канал о кибербезопасности https://max.ru/xakkep_1 Хакер Free Книги, статьи для дизайнеров 📌 https://max.ru/odesigners Статьи, книги для дизайнеров Математика 📌 https://max.ru/Pomatematike Канал по математике https://max.ru/phismat_1 Обучающие видео, книги по Физике и Математике Вакансии в IT📌 https://max.ru/progjob https://max.ru/channel_rabotait Мир технологий 📌 https://max.ru/mir_teh Канал для любознательных Городские📌 https://max.ru/piterspb_78 Свежие новости Санкт-Петербурга https://max.ru/mockva_life Свежие новости Москвы https://max.ru/piterspb Питер Новости: Санкт-Петербург / СПБ / ДТП https://max.ru/channel_krasnodar_novosty Краснодар Новости https://max.ru/channel_novosibirsk_novosti Новосибирск https://max.ru/channel_samara_novosti Новости Самары https://max.ru/channel_ekaterinburg_novosti Новости Екатеринбурга https://max.ru/channel_kazan_novosti Новости Казани https://max.ru/channel_omsk_novosti Новости Омска https://max.ru/channel_moskva_24 Москва 24
854
20
Pake 🤱🏻 Превратите любую веб-страницу в настольное приложение с помощью Rust. Pake поддерживает Mac, Windows и Linux. https
Pake 🤱🏻 Превратите любую веб-страницу в настольное приложение с помощью Rust. Pake поддерживает Mac, Windows и Linux. https://github.com/tw93/Pake 📲 Мы в MAX 👉 @rust_lib
856