Forwarded from You Had No Job
Поправь опечатку:
• Хейт миддл: всё технологии говно, коллеги — чудаки, раньше было лучше
• Хайп миддл: перепишет фронт на Расте, устал от микросервисов и использует макросервисы
• Найт миддл: обожает томатный смузи, никогда не появлялся на утреннем дейли
• Хейт миддл: всё технологии говно, коллеги — чудаки, раньше было лучше
• Хайп миддл: перепишет фронт на Расте, устал от микросервисов и использует макросервисы
• Найт миддл: обожает томатный смузи, никогда не появлялся на утреннем дейли
Forwarded from рандомные картинки
документация к git, идентичная натуральной: https://git-man-page-generator.lokaltog.net/
Блог*
Когда-то я написал на Rust программу, которая переводила числа в строку прописью (т. е. 123 -> "сто двадцать три"). Написал и решил написать статью о том, как написать подобную программу. Это было год назад. Статья всё ещё не готова.
Всё ещё не готова. Кажется, я знаю, чем займусь на выходных
🌚1
#science #article
Замечательная статья про разбор художественного произведения с точки зрения теории информации. А в комментариях дали ссылку на замечательный рассказ Каганова на примерно ту же тему, что и Death Note
Замечательная статья про разбор художественного произведения с точки зрения теории информации. А в комментариях дали ссылку на замечательный рассказ Каганова на примерно ту же тему, что и Death Note
Хабр
Death Note, анонимность и энтропия
В начале “Death Note” местный гениальный детектив по сути занят деанонимизацией: он знает только то, что убийца существует где-то на планете. Никаких улик тот н...
Блог*
Ох, постараюсь уложить это в голове. Есть ещё что-то, что нужно знать о замыканиях? Да. Иногда требуется одно и тоже замыкание передать в качестве аргумента в несколько функций. Клонировать в этом случае не получится, потому что замыкание является клонируемым…
> И будем надеяться, что его не придётся ждать ещё пару месяцев
АХАХАХХАХАХХА
АХАХАХХАХАХХА
Блог*
Ох, постараюсь уложить это в голове. Есть ещё что-то, что нужно знать о замыканиях? Да. Иногда требуется одно и тоже замыкание передать в качестве аргумента в несколько функций. Клонировать в этом случае не получится, потому что замыкание является клонируемым…
#prog #rust #моё
Хроники замыканий
Есть ещё кое-что, что можно сказать про замыкания.
Пожалуй, первое, с чего надо начать — так это с того, что, несмотря на то, что замыкания — это автоматически генерируемые структуры, реализующие определённые трейты, реализовать их самому для своих типов нельзя — по крайней мере, на стабильной версии Rust. Для того, чтобы определить один из Fn*-трейтов для своего типа, нужно активировать две фичи. Первая — fn_traits — позволяет написать определение трейта в обычном виде, а не в засахаренном
Стоп, в Rust есть одноместный кортеж?!
Да. Он объявляется одинаково на уровне термов и на уровне типов:
Надо сказать, что замыкания являются, в сущности, обычными типами, которые отличаются в основном анонимностью. И на них, в частности, нужно в некоторых ситуациях накладывать нужные ограничения. Рассмотрим в качестве примера функцию, которая принимает некоторый счётчик и возвращает замыкание, которое инкрементирует этот счётчик на каждый вызов. Для простоты пусть это будет просто
А разве компилятор не может сам догадаться, как надо?
Нет. Компилятор проверяет правильность расстановки времён жизни, анализируя лишь сигнатуру функции, а не её тело.
Хорошо. Так как нам заставить этот код компилироваться?
Указать явно, что возвращаемое замыкание не может пережить захваченную ссылку. Мы можем сделать это, введя для времени жизни имя и приписав его ссылке и возвращаемому замыканию:
Это связано с тем, как замыкания в Rust работают с захваченными значениями (т. е. со значениями, объявленными снаружи самого замыкания). По умолчанию замыкания захватывают переменные по ссылке (то есть сгенерированный анонимный тип содержит ссылки на эти значения) — мутабельной или иммутабельной, в зависимости от того, как они используются внутри тела замыкания. Использование ключевого слова move переопределяет это поведение по умолчанию и заставляет замыкание захватывать переменные по значению (т. е. перемещает их в замыкание). Если его убрать, то
Так, стоп, так
В правильном или неправильном варианте?
...В правильном
По значению.
Но...
Просто в данном случае само захватываемое значение является ссылкой.
А, я понял. Кажется...
Ничего, это действительно поначалу немного сбивает с толку.
Что ж, это всё, что ты хотел рассказать про замыкания?
Всё? ВСЁ? АХАХХАХАХХАХХА
О_о
Хроники замыканий
Есть ещё кое-что, что можно сказать про замыкания.
Пожалуй, первое, с чего надо начать — так это с того, что, несмотря на то, что замыкания — это автоматически генерируемые структуры, реализующие определённые трейты, реализовать их самому для своих типов нельзя — по крайней мере, на стабильной версии Rust. Для того, чтобы определить один из Fn*-трейтов для своего типа, нужно активировать две фичи. Первая — fn_traits — позволяет написать определение трейта в обычном виде, а не в засахаренном
Fn(Foo) -> Bar
, как обычно. Вторая — unboxed_closures — позволяет определять функции с ABI rust-call
, которое имеют методы Fn*-трейтов. Если мы их используем, то мы можем сделать то, что невозможно на текущей стабильной версии Rust: перегрузку функции по количеству аргументов. Причина, по которой эти трейты не стабилизированы, видимо, состоит в том, что им в качестве ти́пового параметра требуется не произвольный тип, а кортеж типов аргументов. Это выглядит несколько неловко на фоне отсутствия вариадических обобщённых типов, особенно для функции от одного аргумента — его приходится заключать в одноместный кортеж.Стоп, в Rust есть одноместный кортеж?!
Да. Он объявляется одинаково на уровне термов и на уровне типов:
(x,)
Ужас какой. А что ещё можно сказать про замыкания?Надо сказать, что замыкания являются, в сущности, обычными типами, которые отличаются в основном анонимностью. И на них, в частности, нужно в некоторых ситуациях накладывать нужные ограничения. Рассмотрим в качестве примера функцию, которая принимает некоторый счётчик и возвращает замыкание, которое инкрементирует этот счётчик на каждый вызов. Для простоты пусть это будет просто
u32
. Кажется, что можно написать вот так:fn make_incrementer(counter: &mut u32) -> impl FnMut() {, однако этого недостаточно. Дело в том, что возвращаемое замыкание хранит мутабельную ссылку, которая имеет своё время жизни, но это никак не отражено в сигнатуре. Трейты в сигнатурах без явно указанных ограничений времени получают ограничение
move || *counter += 1
}
'static
, что в данном случае явно неверно.А разве компилятор не может сам догадаться, как надо?
Нет. Компилятор проверяет правильность расстановки времён жизни, анализируя лишь сигнатуру функции, а не её тело.
Хорошо. Так как нам заставить этот код компилироваться?
Указать явно, что возвращаемое замыкание не может пережить захваченную ссылку. Мы можем сделать это, введя для времени жизни имя и приписав его ссылке и возвращаемому замыканию:
fn make_incrementer<'a>(counter: &'a mut u32) -> impl FnMut() + 'a { // ......или же мы можем побыть ленивыми и, последовав совету компилятора, навернуть анонимное время жизни:
fn make_incrementer(counter: &mut u32) -> impl FnMut() + '_ { // ...Ясно. А для чего там
move
?Это связано с тем, как замыкания в Rust работают с захваченными значениями (т. е. со значениями, объявленными снаружи самого замыкания). По умолчанию замыкания захватывают переменные по ссылке (то есть сгенерированный анонимный тип содержит ссылки на эти значения) — мутабельной или иммутабельной, в зависимости от того, как они используются внутри тела замыкания. Использование ключевого слова move переопределяет это поведение по умолчанию и заставляет замыкание захватывать переменные по значению (т. е. перемещает их в замыкание). Если его убрать, то
make_counter
не будет компилироваться: аргумент counter
— фактически, локальная переменная — захватывается по ссылке, время жизни которой ограничено скоупом make_counter
, поэтому вернуть такое замыкание за пределы порождающей его функции нельзя.Так, стоп, так
counter
захватывается по ссылке или по значению?В правильном или неправильном варианте?
...В правильном
По значению.
Но...
Просто в данном случае само захватываемое значение является ссылкой.
А, я понял. Кажется...
Ничего, это действительно поначалу немного сбивает с толку.
Что ж, это всё, что ты хотел рассказать про замыкания?
Всё? ВСЁ? АХАХХАХАХХАХХА
О_о