Używam złożonego klucza dla HashMap
w taki sposób, że klucz składa się z dwóch części, a jedna część to String
i nie mogę wymyślić sposobu wyszukiwania za pomocą metody HashMap::get
bez przydzielania nowego String
dla każdego wyszukiwania.Jak uniknąć tymczasowych alokacji przy użyciu złożonego klucza dla HashMap?
Oto niektóre kodu:
#[derive(Debug, Eq, Hash, PartialEq)]
struct Complex {
n: i32,
s: String,
}
impl Complex {
fn new<S: Into<String>>(n: i32, s: S) -> Self {
Complex {
n: n,
s: s.into(),
}
}
}
fn main() {
let mut m = std::collections::HashMap::<Complex, i32>::new();
m.insert(Complex::new(42, "foo"), 123);
// OK, but allocates temporary String
assert_eq!(123, *m.get(&Complex::new(42, "foo")).unwrap());
}
Problem jest z ostatnim twierdzeniem. Przepuszcza, ale wymaga tymczasowej alokacji sterty, ponieważ nie mogę skonstruować obiektu Complex
bez tworzenia obiektu String
.
Aby wyeliminować tymczasowe alokacje w ten sposób, Rust udostępnia cechę Borrow
, z której korzysta metoda HashMap::get
. Rozumiem, jak zrobić Borrow
prac prostych klawiszy, na przykład, rdza biblioteki standardowej za PathBuf
narzędzi Borrow<Path>
poprzez wykorzystanie std::mem::transmute
pod maską, ale nie mogę dowiedzieć się, jak sprawić, by pracować dla mojego Complex
typu:
#[derive(Debug)]
struct Borrowable {
// ??? -- What goes here? Perhaps something like:
n: i32,
s1: &str, // ??? -- But what would the lifetime be? Or maybe:
s2: str, // ??? -- But how would I extend this to a complex type
// containing two or more strings?
}
impl Borrowable {
fn new(n: i32, s: &str) -> &Self {
// ??? -- What goes here? It must not allocate.
unimplemented!();
}
}
impl std::borrow::Borrow<Borrowable> for Complex {
fn borrow(&self) -> &Borrowable {
// ??? -- What goes here? How can I transmute a Complex into a
// &Borrowable?
unimplemented!();
}
}
Wydaje się, że jest to typowy przypadek użycia i podejrzewam, że brakuje mi czegoś ważnego o Borrow
, ale jestem w całkowitej stracie.
Zajrzałeś do [Cow] (https://doc.rust-lang.org/std/borrow/enum.Cow.html)? – Aaronepower