Я пытаюсь разобраться в системе типов Rust.
use std::collections::HashSet;
fn hs_contains<T>(hs: &HashSet<T>, value: &T) -> bool
where
T: PartialEq,
{
hs.iter().any(|v| v == value)
}
fn main() {
// move strings into HashSet
let known_values: HashSet<&str> = ["a", "b", "c"].iter().cloned().collect();
// provided an Vec<String>
let provided_values: Vec<String> = vec!["a".to_string(), "b".to_string(), "z".to_string()];
// hash set of refrences
let mut found: HashSet<&str> = HashSet::new();
found.insert(&provided_values[0]);
found.insert(&provided_values[1]);
found.insert(&provided_values[2]);
let missing: HashSet<_> = known_values.difference(&found).collect();
let value: &String = &provided_values[1];
hs_contains(&known_values, value);
hs_contains(&missing, "c");
println!("missing: {:#?}", missing);
}
( Playground )
Пример кода не компилируется, поскольку типы не приводятся , Можно ли придумать объявление типа для hs_contains
, которое будет удовлетворять условиям внизу примера:
hs_contains(&known_values, value);
hs_contains(&missing, "c");
Почему бы мне просто не использовать HashSet::contains
?
Замена hs_contains
на HashSet::contains
known_values.contains(value);
missing.contains(&"c");
Результатом является следующая ошибка компиляции
error[E0277]: the trait bound `&str: std::borrow::Borrow<std::string::String>` is not satisfied
--> src/main.rs:38:18
|
38 | known_values.contains(value);
| ^^^^^^^^ the trait `std::borrow::Borrow<std::string::String>` is not implemented for `&str`
Единственный другой известный мне способ сделать эту работу -
known_values.iter().any(|v| v == value);
Это вызвало у меня интерес к тому, как определить функцию с объявлением типа, которое могло бы инкапсулировать вышесказанное.