uk
Feedback
Блог*

Блог*

Відкрити в Telegram

Блог со звёздочкой. Много репостов, немножко программирования. Небольшое прикольное комьюнити: @decltype_chat_ptr_t Автор: @insert_reference_here

Показати більше
1 920
Підписники
Немає даних24 години
-17 днів
-1130 день
Архів дописів
photo content

#prog #c #meme

#prog #video Доклад от разработчиков IDE про превратности парсинга #cpp youtube.com/watch?v=WfIr7lKT4Sk

photo content

#meme про... Ножницы

Парочка #meme про твиттер

Этот пост спонсирован редактором ace (используемом на Rust playground). ace — редактор со сломанным поиском.

Так вот, Rust reference гласит, что для default representation enum (а The является именно таковым, потому что на нём нет #[repr]-атрибутов) дискриминанты имеют тип isize (что, однако, не мешает компилятору выбрать тип поменьше для представления enum). Таким образом, обобщённый параметр у self_describing выводится равным возвращаемому типу, т. е. isize. Так какое же значение возвращается? Пойдёт снизу вверх. self_describing принимает тип, ограниченный трейтом SelfValue, и возвращает ассоциированную константу SELF_VALUE; |SelfValue реализован для всех типов T, реализующих GenericValue<T>; | |GenericValue<T> реализован для всех типов, реализующих PairValue<T = isize>; | | |PairValue<T = isize> реализован для isize с PAIR_VALUE = (2, 11); | |GenericValue<isize> реализован для isize с GENERIC_VALUE = t::<isize>(); | | |функция t принимает тип, ограниченный PairValue<T = isize>, и возвращает комбинацию от составляющих T::PAIR_VALUE; | | |для isize функция t возвращает 2 * 11 + 20 = 42; | |<isize as GenericValue<isize>>::GENERIC_VALUE = 42; |<isize as SelfValue>::SELF_VALUE = 42; self_describing::<isize>() == 42; Иными словами, enum The { Answer = 42, } В последней строке создаётся неиспользуемая константа, тип которой задан, как массив длины 42, и которая инициализируется массивом длины The::Answer as usize, то есть 42. Так как типы слева и справа совпадают, то код компилируется (и выдаёт предупреждение о неиспользуемых The и self_describing). То есть "Ответ на главный вопрос жизни, вселенной и всего такого" — это 42, что мы и проверили в Rust на этапе компиляции.

#prog #rust #моё Что ж, наверное, стоит объяснить, а что это вообще за код такой. Странно выглядят фрагменты вроде trait Sеlf { const Sеlf: Self; } и const fn t<T: Т<T = isize>> , поскольку они вроде бы не должны компилироваться из-за совпадающих имён. Дело в том, что я использовал в Sеlf кириллическую е (и в имени трейта, и в имени ассоциированного типа), а в именах трейтов Т и ТТ — соответственно кириллическую Т. Это разрешено с версии Rust 1.53. При этом компилятор выдаёт (помимо всего прочего) вот такое предупреждение на этот код: warning: the usage of Script Group `Cyrillic` in this crate consists solely of mixed script confusables --> src/lib.rs:1:7 | 1 | trait Т { | ^ | = note: the usage includes 'Т' (U+0422), 'е' (U+0435) = note: please recheck to make sure their usages are indeed what you want = note: `#[warn(mixed_script_confusables)]` on by default И также указывает на пары идентификаторов, которые могут быть перепутаны. Полезный компилятор, как ни крути. Если переписать код, чтобы использовать лишь ASCII имена (и заодно привести его под принятые соглашения о наименованиях), то получится следующее: trait PairValue { type T; const PAIR_VALUE: (Self::T, Self::T); } trait GenericValue<T> { const GENERIC_VALUE: T; } trait SelfValue { const SELF_VALUE: Self; } const fn t<T: PairValue<T = isize>>() -> isize { impl<T: GenericValue<T>> SelfValue for T { const SELF_VALUE: Self = T::GENERIC_VALUE; } T::PAIR_VALUE.0 * T::PAIR_VALUE.1 + 20 } const fn self_describing<T: SelfValue>() -> T { impl<T: PairValue<T = isize>> GenericValue<isize> for T { const GENERIC_VALUE: isize = t::<T>(); } T::SELF_VALUE } enum The { Answer = { impl PairValue for isize { type T = isize; const PAIR_VALUE: (isize, isize) = (2, 11); } self_describing() }, } const _ASSERT: [(); 42] = [(); The::Answer as usize]; Вроде выглядит немного получше, но всё ещё запутанно. В Rust, как известно, (почти) всё является выражением. Различного рода top level определения (называемые item в reference) также могут быть использованы, как выражения, и при этом возвращают (). Очень много куда можно воткнуть impl-блок — в частности, внутри функции и внутри выражения. В том числе внутри выражения для дискриминанта варианта enum. Разумеется, при этом применяются обычные правила видимости: нельзя реализовать трейт, если трейт или тип, для которого они определяются, не видны в текущей области видимости, но сами impl-ы трейтов видны всюду, где виден сам трейт. Тут эти правила видимости, впрочем, не мешают. Если вынести на верхний уровень impl-блоки (как я бы и сделал в реальном коде) и немного переупорядочить для ясности, то получится вот это: trait PairValue { type T; const PAIR_VALUE: (Self::T, Self::T); } impl PairValue for isize { type T = isize; const PAIR_VALUE: (isize, isize) = (2, 11); } trait GenericValue<T> { const GENERIC_VALUE: T; } const fn t<T: PairValue<T = isize>>() -> isize { T::PAIR_VALUE.0 * T::PAIR_VALUE.1 + 20 } impl<T: PairValue<T = isize>> GenericValue<isize> for T { const GENERIC_VALUE: isize = t::<T>(); } trait SelfValue { const SELF_VALUE: Self; } impl<T: GenericValue<T>> SelfValue for T { const SELF_VALUE: Self = T::GENERIC_VALUE; } const fn self_describing<T: SelfValue>() -> T { T::SELF_VALUE } enum The { Answer = self_describing(), } const _ASSERT: [(); 42] = [(); The::Answer as usize]; В последней строчке мы находим ответ к загадке этого кода строчку, которая фактически является ассертом времени компиляции на то, что численное значение The::Answer является 42. Откуда берётся это значение? Выше Answer присваивается значение вызова определённой парой строк выше функции self_describing (кстати, использовать трейты на обобщённых параметрах в const fn стало возможным с версии 1.61). Но это обобщённая функция — так какой же тип там выводится?

photo content

#math #meme 🌚

Repost from N/a
photo content

#meme про твиттер (и немного про #game)

Кстати, одна из первых вещей, которая мне бросилась в глаза после прилёта — повсеместные национальные флаги. По крайней мере, в Ереване. Непривычно.

photo content

Раз уж я начал про флаги. #meme

photo content

photo content