Random Rust Dev
364 subscribers
79 photos
41 videos
1 file
28 links
Разработка на языке Rust.
Пишу простыни со своими мыслями о Rust и проектах на нем.
Download Telegram
Зайдите сегодня на godbolt.org Там завезли по-настоящему темную тему, а не вот эти вот темно-серые бэкграунды
🤣10🤩2
Fraction of C++ power
😁11
This media is not supported in your browser
VIEW IN TELEGRAM
👍5
https://docs.rs/amity

Это Раст на меня одного так действует или на всех, что маленький наборчик алгоритмов написаный под собственные сценарии использования хочется положить в красиво оформленную либу, написать документацию и пройтись clippy pedantic, что бы было удобно и красиво?
🔥10😁1
- Эй, ЧатГПТ, я придумал сделать вот такой алгоритм интерполяции фреймов.
Напиши его на питоне, пожалста.
Что б на вход видео принимало, интерполировало и выдавала видео со сгенеренными фреймами.

- Вот код.

<звуки копипасты и запуска из консоли на коротеньком видео>

Ждем
😁9
Немного математики
11🔥2👏2
Ищу интересные магические предметы для персонажей в ДнД.
Вижу "Сфера разрыва донжона".
Ну-ка, ну-ка, как оно там донжоны разрывает?

Donjon’s Sundering Sphere
А я надеялся
😁1
А вот интересно. Есть ли достаточно черная магия, которая позволит написать такие две функции.

const fn IsCalledWith<T>() -> bool { ... }
fn CallItWith<T>() { .. }


заметьте, что const.

По сути я хочу знать, а функция с неким типом вообще где-то в коде вызывается?
И получить const bool
This media is not supported in your browser
VIEW IN TELEGRAM
Давненько ничего я не выкладывал.
Поэтому вот вам видео с геометрической либой.

Первая операция - отражение.

Планируется полный комплект геометрической алгебры для 2д и 3д.

Тулза на коленке сделана для отладки.
🔥8
This media is not supported in your browser
VIEW IN TELEGRAM
Теперь можно отражать и точки и линии в линиях, а потом в отраженных отражать
🔥2👍1
This media is not supported in your browser
VIEW IN TELEGRAM
Как долго написать еще и отражение точек и линий в точке?

Я его написал после того как отправил прошлое видео
1
This media is not supported in your browser
VIEW IN TELEGRAM
Умножаем две линии друг на друга и получаем Motor. Который вращает объекты вокруг точки пересечения линий на удвоенный угол между ними.

А что если они параллельные?
Вращение превращается в линейное движение на удвоенное расстояние между линиями. А формула все та же.
3
Кто угадает как вычисляется пересечение двух линий?
Завершаем базовые функции линией через 2 точки и проекцией точки на линию и линии на точку
This media is not supported in your browser
VIEW IN TELEGRAM
Обычное умножение линий дает мотор, который сдвигает на удвоенное растояние и поворачивает на удвоенный угол между линиями.

Что ж, гораздо удобнее брать от этого умножения квадратный корень.

Теперь, как вы видите, точки следуют за второй линией в той же конфигурации, в какой они находятся у первой линии.
Начинаю регулярную рубрику Rust Tips 🔧

Сегодня - о замечательной функции Cell::from_mut

Она позволяет превратить &mut T в &Cell<T>, что все еще позволяет изменять T, но ее разрешается расшарить
Вот классический пример, где как новичики, так и ветераны спотыкаются о borrow checker

let mut counter = 0;

let mut inc = || counter += 1;
let print = || println!("{}", counter); // cannot borrow `counter` as immutable because it is also borrowed as mutable

inc();
inc();
print();


Передать &mut в inc и одновременно & в print нельзя.

Здесь мы можем использовать магию Cell::from_mut, не изменяя окружающий код.
Обернем ссылку на counter и раздадим в замыкания.


let mut counter = 0;
let cell = Cell::from_mut(&mut counter);

let inc = || cell.set(cell.get() + 1);
let print = || println!("{}", cell.get());

inc();
inc();
print();


🎉 И вуаля - всё работает! 🎉

Бонус для внимательных:
Теперь inc теперь реализует и Fn.
Так что можно тот же трюк использовать что бы передать замыкание, которое что-то мутирует в функцию, которая принимает Fn без Send.
👍195
Сегодняшний Rust Tip об очень полезной функции - Clone::clone_from.

Когда у вас уже есть объект и нужно заменить его клоном другого значения - не спешите писать a = b.clone().
Вместо этого используйте: a.clone_from(&b).

Такой вызов позволяет переиспользовать существующее значение - особенно ресурсы вроде памяти.
Это особенно эффективно при клонировании Box, Vec, String и прочих.

И, конечно, это работает транзитивно.
Вложенный Vec<T> будет клонировать T с помощью clone_from для существующих элементов.
При использовании #[derive(Clone)], компилятор автоматически вызывает clone_from для всех полей.
Но если вы реализуете Clone вручную - подумайте, не стоит ли также переопределить clone_from.
Ведь реализация по умолчанию просто делает *self = other.clone().
Если ваш тип не Copy, clone_from почти наверняка окажется дешевле.

Аналогичная оптимизация есть и у трейта ToOwned.
Для типов вроде str, Path или [T] используйте ToOwned::clone_into(&mut target) вместо target = value.to_owned().

Такие небольшие улучшения могут сэкономить вам годзиллионы процессорных циклов.
И при профилировании вы будете реже видеть, как ваше приложение тратит 90% времени на клонирование и выделение памяти.
👍161
Свежий Rust Tip по свежему stable API

С версии 1.86 в stable стал доступен метод slice::get_disjoint_mut.
Который позволяет получить мутабельные ссылки на разные элементы слайса одновременно.

Разность проверяется методом и при пересечении возвращается ошибка.
Равно как и при индексе вне диапазона.

Вот как его можно использовать

let mut array = [10, 20, 30, 40, 50];

let [a, b, c] = array.get_disjoint_mut([1, 3, 4]).expect("Index overlap");
*a += 100; // 20 -> 120
*b += 100; // 40 -> 140
*c += 100; // 50 -> 150


Так же как get, можно использовать Range, RangeInclusive, RangeFrom, RangeTo и RangeFull, хотя все кроме первых двух для этого метода вряд ли пригодятся.
Так как в метод передается массив, то все должны быть одного типа.


let [a, b, c] = array.get_disjoint_mut([0..2, 2..3, 3..5]).expect("Range overlap");
a.copy_from_slice(&[9, 10]);
b.copy_from_slice(&[11]);
c.copy_from_slice(&[12, 13]);


Похожим методом обзавелся и HashMap, но там вместо возвращения ошибки метод паникует, и возвращает массив Option.

let mut map = HashMap::from([
("a", 1),
("b", 2),
("c", 3),
]);

let [oa, ob] = map.get_disjoint_mut(["a", "b"]);

if let (Some(a), Some(b)) = (oa, ob) {
*a += 10;
*b += 20;
}



Для любителей unsafe есть версии *_unchecked этих методов, которые пропускают проверку непересечения индекстов/диапазонов/ключей.

Удачного вам мулти-индексирования.
🔥10👍3