Что такое решение Rust для универсального контейнера?
Идеальное решение для универсальных контейнеров недоступно пока .Это будет охватываться функцией, которая в настоящее время находится на этапе реализации, универсальными ассоциированными типами (GAT) .
. В настоящее время существуют способы сделать ваши подпрограммы общими для определенных случаев использования.В частности, для функции характерно получение произвольной последовательности данных через значение, которое реализует IntoIterator
:
fn my_number_process<I>(stream: I) -> f32
where
I: IntoIterator<Item = f32>,
{
stream.into_iter().map(|x| x * 2. + 5.).sum().unwrap_or(0.)
}
Для контейнеров, подобных словарю, Index
и IndexMut
черты раскрывают специфические функциональные возможности получения ссылки на значение в получателе по ключу с известным типом.Методы в обоих случаях возвращают &Self::Output
, не оставляя места для исправляемых ошибок или других видов выходных данных.В качестве альтернативы, вы можете создать новую черту, которая подходит для этой цели, пытаясь преодолеть недостаток типов с более высоким родом.В частности, нижеприведенная черта не может быть реализована для простого HashMap
:
trait IMap<K> {
type Value;
fn get<B: Borrow<K>>(&self, key: B) -> Option<Self::Value>;
}
Это связано с тем, что мы не можем указать Value
как &'a V
, где 'a
- это время жизни, которое будет созданокак время жизни self
.Однако его можно реализовать для ссылки на HashMap
:
impl<'a, K, V> IMap<K> for &'a HashMap<K, V>
where
K: Eq,
K: Hash,
{
type Value = &'a V;
fn get<B: Borrow<K>>(&self, key: B) -> Option<Self::Value> {
HashMap::get(self, key.borrow())
}
}
Playground
Аналогичные рассуждения могут быть применены к универсальному контейнеру Set
.