HashMap实现get和insert方法,它们分别采用单个不可变借位和单个值的移动.
我想要一个像这样的特性,但需要两个键而不是一个.它使用里面的地图,但它只是实现的细节.
pub struct Table<A: Eq + Hash, B: Eq + Hash> {
map: HashMap<(A, B), f64>,
}
impl<A: Eq + Hash, B: Eq + Hash> Memory<A, B> for Table<A, B> {
fn get(&self, a: &A, b: &B) -> f64 {
let key: &(A, B) = ??;
*self.map.get(key).unwrap()
}
fn set(&mut self, a: A, b: B, v: f64) {
self.map.insert((a, b), v);
}
}
Run Code Online (Sandbox Code Playgroud) 是否可以使用EntryAPI通过a获取值AsRef<str>,但是将其插入Into<String>?
这是工作示例:
use std::collections::hash_map::{Entry, HashMap};
struct Foo;
#[derive(Default)]
struct Map {
map: HashMap<String, Foo>,
}
impl Map {
fn get(&self, key: impl AsRef<str>) -> &Foo {
self.map.get(key.as_ref()).unwrap()
}
fn create(&mut self, key: impl Into<String>) -> &mut Foo {
match self.map.entry(key.into()) {
Entry::Vacant(entry) => entry.insert(Foo {}),
_ => panic!(),
}
}
fn get_or_create(&mut self, key: impl Into<String>) -> &mut Foo {
match self.map.entry(key.into()) {
Entry::Vacant(entry) => entry.insert(Foo {}),
Entry::Occupied(entry) => entry.into_mut(),
}
}
}
fn …Run Code Online (Sandbox Code Playgroud) 我想删除BTreeMap通过迭代找到的项目.
由于在迭代时无法删除项目,因此我将要删除的项目放入向量中.主要问题是不可能使用引用向量,而只能使用值向量.必须克隆必须删除条目的所有密钥(假设密钥实现了Clone特征).
例如,这个简短的示例不编译:
use std::collections::BTreeMap;
pub fn clean() {
let mut map = BTreeMap::<String, i32>::new();
let mut to_delete = Vec::new();
{
for (k, v) in map.iter() {
if *v > 10 {
to_delete.push(k);
}
}
}
for k in to_delete.drain(..) {
map.remove(k);
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
它在编译时会产生以下错误:
error[E0502]: cannot borrow `map` as mutable because it is also borrowed as immutable
--> src/main.rs:17:9
|
9 | for (k, v) in map.iter() {
| --- …Run Code Online (Sandbox Code Playgroud) 我有一个HashMap<(String, usize), f64>.我也有一个&str和一个usize,我想在HashMap没有克隆的情况下查看.有没有一种方法来查找一(&str, usize)为(String, usize)不知何故?
我想创建一对新类型Tag(str)and TagBuf(String),类似于 howPath和PathBufwrap OsStrand OsString。我的最终目标是拥有一个TagBuf以 为键的地图,并且能够只用一个索引来索引它Tag:
fn main() {
let mut m: HashMap<TagBuf, i32> = HashMap::new();
m.insert(TagBuf("x".to_string()), 1);
assert_eq!(m.get(Tag::new("x")), Some(&1));
}
Run Code Online (Sandbox Code Playgroud)
但是我遇到了问题,因为它Tag是动态大小的。
具体来说,实施起来Borrow<Tag> for TagBuf很棘手:
pub struct Tag(str);
pub struct TagBuf(String);
impl std::borrow::Borrow<Tag> for TagBuf {
fn borrow(&self) -> &Tag {
let s: &str = self.0.as_str();
// How can I turn `&str` into `&Tag`? A naive attempt fails:
&Tag(*s)
}
}
Run Code Online (Sandbox Code Playgroud)
error[E0277]: …Run Code Online (Sandbox Code Playgroud) 我有一个结构,除其他数据外,还有一个唯一的id:
struct Foo {
id: u32,
other_data: u32,
}
Run Code Online (Sandbox Code Playgroud)
我想使用id键作为键并将其保留在结构中:
use std::collections::HashSet;
use std::hash::{Hash, Hasher};
impl PartialEq for Foo {
fn eq(&self, other: &Foo) -> bool {
self.id == other.id
}
}
impl Eq for Foo {}
impl Hash for Foo {
fn hash<H: Hasher>(&self, state: &mut H) {
self.id.hash(state);
}
}
Run Code Online (Sandbox Code Playgroud)
这有效:
pub fn bar() {
let mut baz: HashSet<Foo> = HashSet::new();
baz.insert(Foo {
id: 1,
other_data: 2,
});
let other_data = baz.get(&Foo {
id: …Run Code Online (Sandbox Code Playgroud) 我尝试使用Rust集合(如BTreeMap)来存储键值对以用作排序列表,但我发现它只与精确键匹配.例如,在电话簿案例中,我可以找到具有精确键"David"的项目,但不能找到以"Dav"开头的项目:
use std::collections::BTreeMap;
fn main() {
let mut map = BTreeMap::new();
map.insert("Daniel", "798-1364");
// FOUND WITH EXACT MATCH ONLY
// like map.get(&"Daniel"), Not Found Here
match map.get(&"Dan") {
Some(&number) => println!("Found: {}", number),
_ => println!("Not Found."),
}
}
Run Code Online (Sandbox Code Playgroud)
我可以使用诸如BTreeMap?之类的集合对字符串前缀进行部分匹配吗?
此外,如果我的钥匙是i64s,我可以找到一系列的项目,例如当钥匙大于1000时?我知道如何遍历所有项目,但我想迭代所找到的项目范围.
我可以通过索引访问项目,手动进行二进制搜索吗?