Random Rust Dev
365 subscribers
76 photos
41 videos
1 file
28 links
Разработка на языке Rust.
Пишу простыни со своими мыслями о Rust и проектах на нем.
Download Telegram
Понедельничный Rust Tip.

Простой совет для невыспавшихся за выходные.

Старайтесь не добавлять трейт баунды в объявление типа.
Любой T: Trait потребуют добавить этот баунд во все имплы и функции, кроме случаев, где вместо T будет конкретный тип.

В результате некоторые методы, которые никак не зависят это реализации этого трейта, будут на него завязаны.

Конечно иногда придется. Например если вы используете ассоциированный тип в объявлении полей.
👍6
Запоздалый Rust Tip.

Используйте impl AsRef<T>, impl AsMut<T> и impl Into<T> в аргументах, когда ожидается, что вызываться функция будет удобнее с автоматической конверсией без потери выразительности API.

Но только если T это не дженерик. Иначе придется его явно указывать.

Классический пример это AsRef<Path> аргументы в std всюду, где нужен &Path, потому что удобно вызывать со строковым литералом. При этом на вызывающей стороны не возникает вопросов, куда там оно сконвертируется.

Еще хороший пример - impl Into<EnumType>, где для вариантов есть отдельный тип, который конвертируется в этот вариант. Концептуально они должны быть одним и тем же.

Использовать ли impl Trait или объявить generic, дело вкуса по большей части. Единственная разница в невозможности явно указать тип. Если вы ожидаете, что пользователю функции когда-то понадобится явно указать тип - объявляйте, иначе можно и с анонимным.
👍6👏1💯1
Вот еще один Rust Tip

Делайте derive макросы для своих трейтов.
Если из структуры типа примерно понятно, как реализовать трейт - этот трейт отличный кандидат для derive.
Это значительно уменьшит количество бойлерплейта и уменьшит вероятность глупых ошибок, что мы можем допустить при ручной реализации трейта.

Процедурные макросы могут показаться довольно сложными сначала. Надо парсить и генерировать код.
На самом деле все просто, так как у нас есть крейты syn и quote.
С помощью syn можно без труда распарсить код на Rust, который передается в процедурный макрос. А с помощью иных крейтов можно и содержимое аттрибутов распарсить как по волшебству.
А quote поможет сгенерировать код реализации трейта из шаблона с подстановками.

Не забудьте при генерации Rust кода устанавливать корректные Span-ы. Это поможет пользователю макроса найти причину ошибки.

Так же существует множество надстроек, что делают процедурные макросы вовсе тривиальными. Хотя каждая обладает своими ограничениями.
10👍6
Пятнично.
Я заметил, что у меня есть почти все ачивки в ER.
И не хватало только пары легендарок и 2х концовок.
И у меня был перс, прошедший базу в Jorney 2, кроме ластов.

Что, ж. Собрал леги (пришлось пройти весь квест Ранни, но на это ушел всего час), завалил ластов.
Бегом в Jorney 3. Взял 2 великие руны (Годрик и Райкард), проскочил Линдел, Напрямик к Огненному Гиганту, заваливая только боссов, что встречались по дороге.
Фарум Азула как нож сквозь масло (Jorney 3 кажется проще чем Jorney 2).
Маликет взят с первого пула, несмотря на небольшой факап с бафанием.
На Всезнайке попотел.
Годфри дал жару еще хлеще, оставил его на утро. Утром с первого пула.
Радагон и Зверь с нескольких пулов.

Я точно мучался на Jorney 2 намного больше.
А ведь за весь Jorney 3 я вкачал че-то типа 240-245. Потому что руны с нескольких боссов профукал на вайпах на следующих.

В целом что хочу сказать.
Elden Ring это одна из лучших игр, в какие я играл. Максимально советую всем любителям помахать мечем.
И не бойтесь сложности, она проще чем Dark Souls.
👍5👎4🤷‍♂2
Rust Tip по оптимизации дебажного билда.

В Cargo.toml можно указать, что в dev профиле нужно оптимизировать определенные зависимости.

Такая запись заставит сборщик оптимизировать зависимость foo.

[profile.dev.package.foo]
opt-level = 3


А вот так можно оптимизировать все зависимости разом.

[profile.dev.package."*"]
opt-level = 2


А так будут оптимизировать билдскрипты и процедурные макросы.

[profile.dev.build-override]
opt-level = 3


Оптимизируя зависимости вы ускорите процесс дебега, если только вам не надо заходить внутрь функций зависимости. При необходимости уберите оптимизацию для нее.

Приятного вам дебага.
7👍2💯2
Занимался сегодня рефакторингом небольшого крейта gametime.
Сделал чистку всех предупреждений с clippy::pedantic и задокументировал всё, хоть и минимально.

В крейте функционал для работы со временем в играх.
И минимум сложностей.

Во первых TimeStamp - точка во времени с наносекундной точностью. Относительно чего-то. Обычно относительно того, откуда они берутся.

TimeSpan - промежуток между меньшим и большим TimeStampами. Почти как Duration, но лишь u64 наносекунд.

Clock - часы. Связывают монотонный таймер core::time::Instant и TimeStampы. Генерирует ClockStep, на каждый вызов Clock::step, где есть текущий TimeStamp и TimeSpan между текущим и предыдущим.
Предполагается использовать Clock в главном цикле, делать Clock::step в начале каждой итерации и раздавать ClockStep везде, где нужно знать время.

GlobalClock - как Clock, но используют единую для процесса точку отсчета. Требуется std и global_reference фича

ClockRate - часы со скоростью. Использует внешний источник TimeSpan, генерирует ClockStep с указанной относительной скоростью. Без накапливаемой потери точности.
Удобно для контроля времени в симуляции. Паузы, буллет таймы, перемотки. Просто вся симуляция должна использовать ClockStep из ClockRate, а не общего Clock.

FrequencyTicker - генератор тиков с заданной частотой. Использует внешний TimeSpan и возвращает итератор по ClockStep тиков, произошедших в течение этого времени. Без накапливаемой потери точности.

Ознакомиться с кодом можно здесь.
https://github.com/zakarumych/gametime
🔥9
3😁2💯1
Как объяснить картинкогенератору, что во время прямого удара ногой в живот подошву не видно?

Я сколько не уговаривал, все равно разворачивает ногу подошвой к зрителю.
😁7
😁2😐2
🔥16🫡31👏1
Для тех кто рос в 90е
🔥14😁7
Теперь можно на целый день убежать от семьи в свой "офис" :)
😁62
Класть разные замыкания во враппер без аллокаций это конечно круто.

Но еще круче, когда в сигнатурах могут быть лайфтаймы и и высокоранковые лайфтаймы.
🤯13👍4😱1
Кстати говоря,
бесцветные зеленые идеи спят яростно.

А я тем временем пробую chumsky для написания парсера моего игрушечного языка.
👍4
Попробовал Codex от OpenAI.

Плюсы:
Он нашел в одном месте баг, где я вместо min написал max. И добавил юнит тест на этот код.

Минусы:
Попросил его написать за меня парсер.
Он написал игрушечный нерабочий парсер, где Expr это просто SmolStr, а Operators ограничивается вариантом Add, и вообще все не то, как я описал синтаксис.
Попросил переделать - ответил, что ему слишком сложно.

Вывод:
Можно время от времени просить найти баги в репе. Найдет - хорошо. Не найдет - ну и ладно.
В обучающем датасете слишком много кода из туториалов.
👍6💯1
Как почувствовать себя хакером. Пошаговая инструкция:

1. Зайдите в кафе или заправку, где посетитель сам использует кофе-машину.

2. Получите сообщение об ошибке.

3. Нажмите на незаметную кнопочку на сенсорном экране, что бы открыть админское меню.

4. Угадайте пин с первого раза. Например 1111.

5. Перезагрузите кофе-машину.

6. Сделайте себе кофе.

7. Наслаждайся своим кофе, хакерман. (Или хакервуман. Но есть ли такие у меня в подписчиках, даже не знаю.)
7🔥2👨‍💻1😎1
Не могу понять прикола.

Работаю потихоньку над арканой, но как только надо делать импорт ассетов начинаю забивать.

Потом снова берусь делать что-то другое. И опять, сел делать ассеты, потупил 10 минут и переключился на поиграть.
9
Статическая типизация?
Динамическая типизация?
Галюцинатическая типизация!
😁182👍2🙈2🔥1🦄1
Немного юморов в... пустоту
3👍1