在不分配新字符串的情况下检查 HashSet<Rc<String>> 中是否包含字符串切片
Check if a string slice is contained in HashSet<Rc<String>> without allocating a new String
我正在缓存来自 HashSet<Rc<String>>
中输入的单词。
在检查它是否包含在集合中时,我可以以某种方式使用 &str
作为该集合的键吗?HashSet<String>
?
使用 HashSet<String>
,有效:
use std::rc::Rc;
use std::collections::HashSet;
let input = "";
let string = input.to_string();
let rc_string: Rc<String> = Rc::new(string.clone());
let set: HashSet<String> = [string.clone()].iter().cloned().collect();
assert!(set.contains(&string));
assert!(set.contains(input));
但是如果我尝试使用 HashSet<Rc<String>>
:
let string_cache: HashSet<Rc<String>> = [rc_string.clone()].iter().cloned().collect();
assert!(string_cache.contains(&rc_string));
assert!(string_cache.contains(&string));
assert!(string_cache.contains(input));
然后我得到这个错误:
error[E0277]: the trait bound `std::rc::Rc<std::string::String>: std::borrow::Borrow<str>` is not satisfied
--> src/main.rs:16:26
|
16 | assert!(string_cache.contains(input));
| ^^^^^^^^ the trait `std::borrow::Borrow<str>` is not implemented for `std::rc::Rc<std::string::String>`
|
= help: the following implementations were found:
<std::rc::Rc<T> as std::borrow::Borrow<T>>
如错误消息所述,HashSet::contains
要求存储在集合中的项目类型对其参数类型具有 Borrow
实现。 Rc<String>
没有 Borrow<str>
的实现。
您不能自己添加此实现,因为涉及的类型和特征都不是来自您的板条箱。但是,您可以为 Rc<String>
创建一个新类型包装器并实现您可能需要的任何 Borrow
实现:
#[derive(Debug, Eq, PartialEq, Hash)]
struct CacheItem(Rc<String>);
impl Borrow<str> for CacheItem {
fn borrow(&self) -> &str {
&self.0
}
}
impl Borrow<String> for CacheItem {
fn borrow(&self) -> &String {
&self.0
}
}
impl Borrow<Rc<String>> for CacheItem {
fn borrow(&self) -> &Rc<String> {
&self.0
}
}
let string_cache: HashSet<CacheItem> = [rc_string.clone()].iter().cloned().map(CacheItem).collect();
assert!(string_cache.contains(&rc_string));
assert!(string_cache.contains(&string));
assert!(string_cache.contains(input));
像这样构造的新型包装器应该具有零运行时成本。但是,您可能需要添加一些额外的特征实现才能方便地使用它。
我正在缓存来自 HashSet<Rc<String>>
中输入的单词。
在检查它是否包含在集合中时,我可以以某种方式使用 &str
作为该集合的键吗?HashSet<String>
?
使用 HashSet<String>
,有效:
use std::rc::Rc;
use std::collections::HashSet;
let input = "";
let string = input.to_string();
let rc_string: Rc<String> = Rc::new(string.clone());
let set: HashSet<String> = [string.clone()].iter().cloned().collect();
assert!(set.contains(&string));
assert!(set.contains(input));
但是如果我尝试使用 HashSet<Rc<String>>
:
let string_cache: HashSet<Rc<String>> = [rc_string.clone()].iter().cloned().collect();
assert!(string_cache.contains(&rc_string));
assert!(string_cache.contains(&string));
assert!(string_cache.contains(input));
然后我得到这个错误:
error[E0277]: the trait bound `std::rc::Rc<std::string::String>: std::borrow::Borrow<str>` is not satisfied
--> src/main.rs:16:26
|
16 | assert!(string_cache.contains(input));
| ^^^^^^^^ the trait `std::borrow::Borrow<str>` is not implemented for `std::rc::Rc<std::string::String>`
|
= help: the following implementations were found:
<std::rc::Rc<T> as std::borrow::Borrow<T>>
如错误消息所述,HashSet::contains
要求存储在集合中的项目类型对其参数类型具有 Borrow
实现。 Rc<String>
没有 Borrow<str>
的实现。
您不能自己添加此实现,因为涉及的类型和特征都不是来自您的板条箱。但是,您可以为 Rc<String>
创建一个新类型包装器并实现您可能需要的任何 Borrow
实现:
#[derive(Debug, Eq, PartialEq, Hash)]
struct CacheItem(Rc<String>);
impl Borrow<str> for CacheItem {
fn borrow(&self) -> &str {
&self.0
}
}
impl Borrow<String> for CacheItem {
fn borrow(&self) -> &String {
&self.0
}
}
impl Borrow<Rc<String>> for CacheItem {
fn borrow(&self) -> &Rc<String> {
&self.0
}
}
let string_cache: HashSet<CacheItem> = [rc_string.clone()].iter().cloned().map(CacheItem).collect();
assert!(string_cache.contains(&rc_string));
assert!(string_cache.contains(&string));
assert!(string_cache.contains(input));
像这样构造的新型包装器应该具有零运行时成本。但是,您可能需要添加一些额外的特征实现才能方便地使用它。