1.83K subscribers
3.3K photos
132 videos
15 files
3.58K links
Блог со звёздочкой.

Много репостов, немножко программирования.

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Forwarded from You Had No Job
Грузчик-тестировщик для проведения нагрузочного тестирования
Любопытный, но довольно бесполезный пример полиморфизма в Go

В гошечке есть несколько способов писать полиморфные функции:

1. интерфейсы;
2. тайп свитчи и тайп кастинг интерфейсов;
3. рефлексия;

Недавно мне понял, что есть чётвёртый подход, который стал возможен с появлением type alias — назовём его апкастингом типов. Работает оно так:

func main() {
printName(Cat{"Whiskey"})
printName(Dog{"Chappie"})
}

type Cat struct { Name string }

type Dog struct { Name string }

type named = struct { Name string }

func printName(n named) {
fmt.Println(n.Name)
}

В спеке Go указано, что присваивание x типа V к переменной типа T валидно в случае, если V и T основаны на одинаковых типах и T — не именованный тип ("x's type V and T have identical underlying types and at least one of V or T is not a defined type."). Псевдонимы типов не считются именованными типами, так что мы можем принимать в аргумент n любую кастуемую структуру.

К сожалению, это не слишком полезно — наверное только если вы не хотите делать пачку геттеров и у вас есть пачка одинаковых структур разных типов.
#prog #rust

Мне недавно мой друг @ilyavenner подкинул такую задачу:

"
fn f() -> i32 {
unsafe { core::hint::unreachable_unchecked() }
}

задача:
предотвратить неопределённое поведение при вызове функции

условия:
1. запрещено изменять тело функции;
2. исправленная версия функции не должна мешать остальному коду компилироваться (если она нигде не вызывается)"

Надо отметить, что из-за безусловного вызова unreachable_unchecked данную функцию в принципе нельзя вызвать, не вызывая неопределённого поведения, но это в данном случае роли не играет.

Мои первые попытки решить эту задачу были скорее читерскими: отклонить MR, добавляющий эту функцию (передаю привет своим коллегам) или просто обернуть функцию в /* */ . В рабочем чате коллеги предлагали и аналогичные пути решения проблемы, вроде #[cfg(some_defintely_non_existent_feature_name)] или #[cfg(all(x, not(x)))]. Есть, однако и более тонкие пути разрешения проблемы.

Для того, чтобы вызвать функцию, нужно сначала предоставить ей аргументы (это справедливо только для энергичного (call-by-value) языка, коим является Rust). А что, если тип аргумента ненаселён? В этом случае создать значение аргумента будет невозможно (нормальное, а не через днище), поэтому вызывать функцию будет нельзя:

fn f(_: ::core::convert::Infallible) -> i32 {
unsafe { core::hint::unreachable_unchecked() }
}

Однако, как показал Илья, эту красивую вещь можно обойти при помощи unsafe:

unsafe { f(core::mem::transmute::<_, core::convert::Infallible>(())); }


Да, transmute проверяет, что оба типы — входной и возвращаемый — имеют один и тот же размер (из-за чего её в общем случае нельзя использовать в обобщенных контекстах), однако компилятор Rust считает, что ненаселённые типы имеют размер 0 байт — практическая полезная аппроксимация, но не совсем верная.

Так что же, надежда совсем потеряна? Отнюдь. Илья показал решение, до которого я, к своему стыду, не додумался:

fn f<T: Copy + Drop>() -> i32 {
unsafe { core::hint::unreachable_unchecked() }
}

Дело в том, что ни один тип в Rust не может одновременно реализовывать Drop и Copy. Вызов этой функции потребует инстанцировать T неким типом, а его нет и быть не может. Более того, использовать transmute для обхода не получится, поскольку для этого нужно, опять-таки, конкретизировать тип f, что невозможно сделать. Вот она, сила типов!
Ничто так не бодрит с утра
Forwarded from ozkriff.games 🦀 (Andrey @ozkriff Lesnikóv)
Когда твоя жена - ветеринар, то это не только много живности в доме, но и, внезапно, крабоугодные иконы от её коллег ветеринаров-художниц.

Я теперь, видимо, сертифицированный Rust-евангелист.

Клац-клац! 🦀
Редкие эпизоды из абсурдной жизни программиста.

"Две пиццы — это не про размер команды, а про размер фонда оплаты труда"

@topizza #blogrecommendation
#prog #meme #rust

Коротко про то, как большинство видят мой канал
Плюсы и минусы калькулятора

Плюсы:
Минусы:
👍2😁1
Пока что самая оригинальная открытка, которую видел
Forwarded from 🇺🇦 Go for two :)
Happy New Year’; DROP TABLE 2020;--
Эт самое
С Новым Годом
Не ждите ни развёрнутых новогодних представлений — их вы и так уже услышали достаточно, чтобы они смешались в однородную массу счастьяздоровьябогаствавсегонаилучшего — ни итогов года, потому что, во-первых, они переоценены, а во-вторых, я уже суммировал всё, что мне было важно, на дне рождения Блог*а (https://t.iss.one/dereference_pointer_there/1405), и с тех пор ничего нового не прибавилось
Forwarded from мне не нравится реальность (вафель 🧇🍓)
ah yes день "и тебя тоже"
Блог*
Лучший пост?
Опрос завершён (с всего 89 голосов — где вы все?!). Не буду проходится по всем пунктам — иначе это слишком уж походит на самолюбование — хочу отметить лишь наиболее популярный вариант.

Пост про регулярные выражения. Честно говоря, я удивлён. Ну то есть, я писал о куда как более продвинутых вещах, а здесь я даже кода никакого не привёл. В чём же дело? Я вижу две возможные причины.

Во-первых, это тема, понятная и близкая многим разработчикам, да и, в общем-то, также и некоторым из тех, кто программистом не является. Остальные авторские посты у меня погружаются в костыли тонкости Rust — языка всё ещё не особо широко распространённого, а регулярные выражения — это то, пост про что можно скинуть коллеге.

Во-вторых, да, тон поста. Если в других постах я обычно стараюсь выдерживать относительно нейтральный тон, то тут я дал волю своему раздражению и щедро сдобрил пост речевой мишурой. Является ли это фактором внимания в силу самого тона как такого или в силу того, что пост столь сильно выбивается среди остальных — мне неизвестно.

А что вы можете сказать по этому поводу? Серьёзно, почему?
#prog #rust #rustreleasenotes

А тем временем вышла версия Rust 1.49.0 🎉. Конечно, вы можете прочитать пост в официальном блоге, но там по традиции пишут не всё, а я, как обычно, нововведения обозреваю выборочно.

Наиболее значимое с точки зрения кровавого энтерпрайза изменение — это поднятие уровня поддержки таргета aarch64-unknown-linux-gnu до tier 1, то есть компилятор гарантированно собирает исполняемые файлы для данной платформы, и для этой платформы обязательны прохождения полного набора тестов. Это изменение значимо не только из-за того, что убирает одно из препятствий на пути к использованию Rust на всё растущем количестве ARM-устройств, но и потому, что это первая не-x86 платформа, которая добралась до tier 1. Это не единственный ARM-таргет, получивший внимание — до tier 2 подняли поддержку aarch64-apple-darwin (да, это M1) и aarch64-pc-windows-msvc.

Впрочем, для тех, кто разрабатывает на Rust под x86, это не столь интересное изменение. А вот что является универсальным улучшением — так это появившаяся теперь возможность привязывать в одном и том же паттерне одновременно и по значению, и по ссылке — честно говоря, я удивлён, что про это в официальном блоге ничего не сказано. Короткий пример:

let [foo, ref bar] = [String::from("foo"), String::from("bar")];

Неразмеченные объединения (union) теперь могут реализовывать Drop. Стабилизирована эта фича именно так, как и предполагалась: в объединении всё так же не разрешается иметь поля, реализующие Drop, так что их надо заворачивать в ManuallyDrop. Для конечных пользователей языка это означает главным образом то, что всякие SmallVec/SmallString, хранящие элементы на стеке при небольшом их количестве, теперь могут переиспользовать память при помощи union на стабильной версии компилятора и не хранить тег, то есть простое обновление компилятора и библиотеки срежет несколько байт с размеров этих типов вообще без каких-либо дополнительных телодвижений. Ну, в идеале.

Массивы всех размеров теперь реализуют Index{, Mut}<всё, чем можно индексировать слайс>. Казалось бы, мелочь, поскольку индексация работала и до этого через deref coercion, но до влития этого PR реализация для массива индексации собственным типом ломала индексацию через usize и всякие Range*.

Ну и наконец, как я уже писал, наконец-то стабилизировали select_nth_unstable{, _by{, _key}}, ю-ху! Теперь можно на изи извлекать n наименьших/наибольших элементов без аллокаций. Дупликации кода тут нет, поскольку это те же алгоритмы, которые и так использовались внутри реализации нестабильных сортировок (что, впрочем, лишь усиливает вопросы о причине долгого срока стабилизации).

Короче — хороший, годный релиз.

P. S.: так как я тоже писал не всё — вот полные записи о релизе.