TGViewer
Блог* Блог* @dereference_pointer_there · 1.99K subscribers
Post #10747 1.11K
#prog #rust #article

В стандартной библиотеке Rust есть несколько ассоциативных контейнеров: HashMap, HashSet, BTreeMap и BTreeSet. Часто на практике в качестве ключей в них хранятся строки — String. Требовать от пользователя для поиска значение типа String неудобно и чревато проблемами в производительности. Потому у этих структур данных есть API, позволяющие использовать для поиска ключи других, "похожие" на те, что хранятся в контейнере.

Возьмём в качестве примера HashMap::get:

fn get<Q>(&self, k: &Q) -> Option<&V>
where
K: Borrow<Q>,
Q: Hash + Eq + ?Sized,


Как видно из кода, тип для поиска (Q) не обязан совпадать с типом хранимых ключей (K), но на K есть ограничение K: Borrow<Q>. Трейт Borrow выглядит таким образом:

trait Borrow<Borrowed>
where
Borrowed: ?Sized,
{
fn borrow(&self) -> &Borrowed;
}


В процессе поиска значения на хранимых ключах вызывается метод <K as Borrow<Q>>::borrow, и результат возвращаемого значения сравнивается со значением, переданным в get. Именно благодаря этому API (и реализациям в std, разумеется) коллекцию HashMap<String, Thing> можно индексировать значениями типа &str.

Но у этого API есть недостаток. Именно, оно требует, чтобы предоставляемое значение было ссылкой и чтобы из ссылки на ключ можно было получить ссылку на Q. Это ограничивает применимость API. Если, например, в мапе в качестве ключей хранятся (String, String), то логичный невладеющий эквивалент для индексации (&str, &str) не будет работать, потому что это кортеж ссылок, а не ссылка.

В короткой статье Borrowed tuple indexing for HashMap рассказывается, как с некоторым количеством бойлерплейта можно обойти это ограничение.

Для сравнения, hashbrown (поверх которого сделаны мапы в std) от подобных ограничений не страдает, поскольку там в API используется более гибкий трейт Equivalent:

trait Equivalent<K>
where
K: ?Sized,
{
fn equivalent(&self, key: &K) -> bool;
}
  • 👍 10
  • 🤯 3
  • 🤡 1
More from @dereference_pointer_there
  1. Oct 9, 2026#prog #rust #meme Было в r/rustjerk, но сначала выложили в r/ClaudeCode
  2. Oct 9, 2026Welp
  3. Oct 9, 2026#prog #article Оттуда: The case against JPEG XL
  4. Oct 9, 2026#prog #article Shipping JPEG XL in Chrome Но в треде на r/rust пишут, что есть сомнения в…
  5. Oct 9, 2026#prog #rust #rustlib hashify v0.3: compile-time perfect hashing, now 4 to 12 times faster…
  6. Oct 9, 2026#prog #meme про... Slop
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →