我正在使用一个复杂的密钥,HashMap使得密钥包含两个部分,一个部分是a String,我无法弄清楚如何通过该HashMap::get方法进行查找而不String为每个查找分配新的.
这是一些代码:
#[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());
}
Run Code Online (Sandbox Code Playgroud)
问题出在最后的断言上.它通过,但它需要临时堆分配,因为我不能构造一个Complex没有构造一个String.
为了消除这样的临时分配,Rust提供了Borrow该HashMap::get方法使用的特征.我理解如何Borrow为简单的键工作.例如,Rust标准库的PathBuf实现Borrow<Path> …
我想插入一个HashMap,但保持一个不可变的借用密钥传递到地方.在我的情况下,键是字符串.
这是一种方式:
use std::collections::HashMap;
let mut map = HashMap::new();
let id = "data".to_string(); // This needs to be a String
let cloned = id.clone();
map.insert(id, 5);
let one = map.get(&cloned);
let two = map.get("data");
println!("{:?}", (one, two));
Run Code Online (Sandbox Code Playgroud)
但这需要克隆.
这个工作直到Rust 1.2.0:
use std::collections::HashMap;
use std::rc::Rc;
use std::string::as_string;
let mut map = HashMap::new();
let data = Rc::new("data".to_string()); // This needs to be a String
let copy = data.clone();
map.insert(data, 5);
let one = map.get(©);
let two = map.get(&*as_string("data"));
println!("{:?}", (one, two));
Run Code Online (Sandbox Code Playgroud)
如何使用Rust …
我有一个收藏Foo。
struct Foo {
k: String,
v: String,
}
Run Code Online (Sandbox Code Playgroud)
我想要一个HashMap具有键&foo.k和值的键foo。
显然,不Foo通过引入Rc或克隆/复制进行重新设计是不可能的k。
fn t1() {
let foo = Foo { k: "k".to_string(), v: "v".to_string() };
let mut a: HashMap<&str, Foo> = HashMap::new();
a.insert(&foo.k, foo); // Error
}
Run Code Online (Sandbox Code Playgroud)
get()从HashSet(Playground)滥用似乎有一种解决方法:
use std::collections::{HashMap, HashSet};
use std::hash::{Hash, Hasher, BuildHasher};
use std::collections::hash_map::Entry::*;
struct Foo {
k: String,
v: String,
}
impl PartialEq for Foo {
fn eq(&self, …Run Code Online (Sandbox Code Playgroud) 我有一个包含唯一ID的结构,并使用该ID作为其哈希值:
use std::borrow::Borrow;
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
type Id = u32;
#[derive(Debug, Eq)]
struct Foo {
id: Id,
other_data: u32,
}
impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
self.id == other.id
}
}
impl Hash for Foo {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
impl Borrow<Id> for Foo {
fn borrow(&self) -> &Id {
&self.id
}
}
Run Code Online (Sandbox Code Playgroud)
我了解Foo::id一旦将值放入,就无法修改它的值,HashSet因为那样会改变哈希值。但是,我想修改Foo::other_data。我知道我可以将其从中删除HashSet,进行修改,然后再次插入,但是这样的方法get_mut()会更加干净。有没有办法完成这样的事情:
fn main() …Run Code Online (Sandbox Code Playgroud)