ch
Feedback
Блог*

Блог*

前往频道在 Telegram

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

显示更多
1 924
订阅者
-224 小时
无数据7
-130
帖子存档
В кои-то веки #successstory

😭 (сайт — releases.rs)
😭 (сайт — releases.rs)

photo content

photo content

Ну, почти
Ну, почти

(ну так-то, конечно, не колготок, а чулков) Source
(ну так-то, конечно, не колготок, а чулков) Source

#prog #abnormalprogramming spellscript
esotoric [sic!] programming language that's read like a spellbook
begin the grimoire.
summon the power with essence of 7.
conjure ritual named amplify with value to return value multiplied by value.
enchant power with essence 0 of through ritual amplify with power.
inscribe whispers of "the power is amplified: " bound with power.
close the grimoire.
output: the power is amplified: 49

#prog #article That boolean should probably be something else
By storing a boolean as our data, we're coupling that data tightly to our application logic. Instead, we should remain critical and ask what data the boolean depends on, and should we maybe store that instead?
Да, про сумм-типы там тоже упоминается.

photo content

#prog #rust #abnormalprogramming fibonacci-numbers crate with self-recursive dependencies
I have created a crate called fibonacci-numbers. There are 187 different major versions of the crate, each exporting the Fibonacci number corresponding to that version. <...> Version 186 depends on version 184 and 185 and exports the largest Fibonacci number that fits in a u128:
pub const VALUE: u128 = fib184::VALUE + fib185::VALUE;

Демидович -> Demidovich -> Полуголубкин (#лингво)

Почему "национализация" означает "переход в собственность государства", а не "превращение в страну"?

photo content

#meme про кота (thanks @memegelion)
#meme про кота (thanks @memegelion)

+1
+1

Папищек подсказывает, что в std Rust предлагают добавить метод для работы с подобными случаями, и, более того, предложение ссылается на ту же статью

Надо отметить, что первый пример с оптимизацией действительно не компилируется в лоб, но это не значит, что от аллокации в цикле нельзя избавиться. Именно, вот такой код с использованием bumpalo компилируется:
fn process_source(sources: Vec<Source>) {
    let b = bumpalo::Bump::new();
    for source in sources {
        let data = source.fetch_data();
        let mut buffer = bumpalo::collections::Vec::new_in(&b);
        buffer.extend(data.split(splitter);
        process_data(&buffer);
    }
}
В этом коде арена, которая в реализации и выделяет память, конструируется один раз за пределами цикла и позволяет переиспользовать память, но версия вектора из bumpalo создаётся заново на каждой итерации и потому может позволить себе иметь время жизни, сравнимое с временами жизни переменной итерации. Вызывать при этом явно .clear() за счёт RAII не требуется.

#prog #cpp #rust #article Why we didn't rewrite our feed handler in Rust Отдельно отмечается, что Rust в технологическом стеке в этой компании уже есть и успешно используется. Проблемы возникли с переписыванием конкретного компонента, который уже есть и написан на C++. Конкретно в тексте приведены три паттерна, которые валидны в C++ и не выразимы или выразимы неудобно на Rust. Первое касается ограничений borrow checker-а. Вот какой пример приводят:
fn process_source(sources: Vec<Source>) {
    for source in sources {
        let mut buffer: Vec<&[u8]> = Vec::new();
        let data: Vec<u8> = source.fetch_data();
        buffer.extend(data.split(splitter));
        process_data(&buffer);
    }
}
Простой и понятный код — но, к сожалению, выделяющий память в цикле. Логично было бы вынести аллокацию за цикл и очищать буфер в конце — но тогда компилятор не даёт скомпилировать код:
error[E0597]: `data` does not live long enough
  --> src/lib.rs:32:23
   |
31 |         let data: Vec<u8> = source.fetch_data();
   |             ---- binding `data` declared here
32 |         buffer.extend(data.split(splitter));
   |         ------        ^^^^ borrowed value does not live long enough
   |         |
   |         borrow later used here
33 |         process_data(&buffer);
34 |     }
   |     - `data` dropped here while still borrowed
Второй паттерн — самоссылающиеся структуры, известная больная тема в Rust. Третий паттерн — множество определений разных версий и унифицированный код для работы с ними (из-за необходимости поддержки разных версий схем обмена данных, насколько я понял). Пример из статьи на C++:
struct RecV1 {
    uint32_t x;
    uint32_t y;
}

struct RecV2 {
    uint32_t x;
    uint32_t y;
    uint32_t z;
}
Унифицированный код для работы с обоими этими типами можно написать при помощи шаблонов:
template <typename T>
T InitRec() {
    T res;
    res.x = 1;
    res.y = 2;
    if constexpr(std::is_same_v<T, RecV2>()) {
        res.z = 3;
    }
    return res;
}
Нетрудно видеть, как это обобщается на случай большего количества полей и различных версий. В Rust можно попробовать сделать нечто подобное, но это вырождается в бойлерплейт, облегчать который приходится макросами — иными словами, попытка повторить шаблоны из C++.

#prog #article Know your SCM_RIGHTS TIL что в Linux (на самом деле UNIX) есть способ передавать файловые дескрипторы между процессами. И эти файловые дескрипторы могут быть в том числе TCP- и UDP-сокетами.