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

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

Небольшое прикольное комьюнити: @decltype_chat_ptr_t
Автор: @insert_reference_here
Download Telegram
Forwarded from 🍑 Hairy Peach 🇺🇦 (Ro Ver)
#prog #rust #performancetrap #article

Статья о том, как апгрейд до новой версии tokio привёл к тому, что сервер, обычно отвечающий меньше, чем за миллисекунду, начал отвечать ровно за 40 миллисекунд. Спойлер: как всегда в подобных случаях, баг образовался из-за взаимодействия нескольких механизмов, включая части из linux.
#prog #rust #rustlib

Библиотека spirit — для снижения количества бойлерплейта при написании долгоживущих серверов. Логгирование, перечитывание конфигов при изменении, реагирование на сигналы, оборачивание в демоны — вот это вот всё.
#prog #rust #rustlib #amazingopensource

Заметки о библиотеке для использования постфиксных макросов, с изложением мотивации для её создания, истории вопроса и немного о реализации.

use postfix_macros::{postfix_macros, unwrap_or};

fn main() {
postfix_macros! {
let urls = ["https://rust-lang.org", "https://github.com"];
for url in urls.iter() {
let mut url_splitter = url.splitn(2, ':');
let scheme = url_splitter.next().unwrap();
let _remainder = url_splitter.next().unwrap_or! {
println!("Ignoring URL: No scheme found");
continue;
};
println!("scheme is {}", scheme);
}
}
}
Мои знакомые — особенно те, кто сами ведут свой канал в Телеграм — спрашивают, как мне удаётся постить качественный контент каждый день.

Ответ очень прост: я выкладываю некачественный контент.
#psy

О том, как правильно извиняться. Написано в контексте брака, но, на мой взгляд, вполне применимо и в более общих ситуациях.
TL;DR: Извиняетесь, но не заставляйте просить прощения

В
этот раз ссылка на приватный канал в Telegram, так что вот вам сначала инвайт, а потом уже и ссылка на сам пост.
Forwarded from <илья as Человек> (ilya sheprut)
блять, опять я всё своё свободное время потратил в телегу и нихера не напрогал. Надо удалять её нафиг
#prog #cpp

twitter.com/AffectiveCpp — лучший твиттер-аккаунт о C++. Полезен даже профессионалам, а новичкам так и вовсе практически обязателен.
#prog #rust tip: спецификатор фрагмента vis в макросах сопоставляется с описанием видимости определения, в том числе и пустым.

К примеру, следующий код компилируется:

macro_rules! accept_with_vis {
($vis:vis struct $name:ident;) => {}
}

accept_with_vis!{struct Foo;}
#prog #rust #моё

Как многие из вас знают (а если не знаете — узнаете сейчас), в Rust нельзя перемещать (move) поля из значения типа, имеющего нетривиальную реализацию Drop. В частности, значение типа, реализующего Drop, нельзя деструктурировать. Однако надо отметить, что если тип поля реализует Copy, то к этому полю можно обратиться, в том числе и пре деструктуризации, при этом значение этого поля скопируется. Проиллюстрирую только что сказанное:

struct NonCopy;

struct Dropping<T>(T, NonCopy);

impl<T> Drop for Dropping<T> {
fn drop(&mut self) {
println!("dropped");
}
}

fn main() {
// ⬇️ если раскомментировать эту строку, то программа не скомпилируется с E0509
// let Dropping(_non_copy, _) = Dropping(NonCopy, NonCopy);

// А вот это — компилируется и печатает "dropped".
// Обратите внимание, паттерн `_`
*не* перемещает значение.
let Dropping(_x, _) = Dropping(0_u32, NonCopy);
}

Где это может выстрелить? При написании биндингов к сишным либам. Одна их техник обеспечения инкапсуляции в C — это определение структуры в заголовочном файле без определения её полей. Это позволяет получить доступ к полям структуры только там, где дано её определение, а внешний код может обращаться к ней лишь по указателю. И указатель — это Copy-тип, да.

Пусть это выглядит примерно так:

extern "C" {
// extern types ещё не стабилизированы, так что
// в реальной библиотеке, скорее всего, будут использовать *mut std::ffi::c_void
    type Some_C_Struct;
fn c_lib_release_resources(arg: *mut Some_C_Struct);
}

struct Handle(*mut Some_C_Struct);

impl Drop for Handle {
fn drop(&mut self) {
unsafe { c_lib_release_resources(self.0) }
}
}

Что произойдёт, если мы попытаемся деструктурировать Handle? Скажем, нам зачем-то потребовалась реализация метода leak:

impl Handle {
fn leak(self) -> *mut Some_C_Struct {
// Здесь мы разбираем значение, но так как указатель — Copy-тип,
// имя ptr привязывается к копии значения, перемещения не происходит.
let Handle(ptr) = self; // <-- после этой точки с запятой кончается время жизни self, и вызывается деструктор
// Ура, у нас на руках невалидный указатель!
ptr
}
}

Что можно с этим сделать? Использовать ManuallyDrop. Этот тип предотвращает вызов деструктора (а также деструктуризацию, поскольку у него приватные поля), но при этом не предотвращает доступ к полям значения внутри (через Deref). Возникает вопрос, почему не использовать std::mem::forget? В принципе, в документации подробно расписано, но если коротко, то std::mem::forget значительно сложнее корректно использовать.
Сишный код в двух словах:

Бе ды
с
вла дением
Прошу прощения, в предыдущем опросе один диапазон возрастов просто не был представлен
Сколько вам лет?
(диапазон с включающей нижней и исключающей верхней границами)
Final Results
1%
0..10
7%
10..18
41%
18..25
25%
25..30
13%
30..35
7%
35..40
2%
40..45
1%
45..50
1%
50..60
1%
60..∞
Блог* pinned «Сколько вам лет?
(диапазон с включающей нижней и исключающей верхней границами)
»
Если вы не можете, потому что у вас лапки — значит, вы котик.