Rust 如何从哈希集形成切片?
结构定义为:Rust 如何从哈希集形成切片?,rust,lifetime,Rust,Lifetime,结构定义为: struct Node { set: HashSet<usize>, // other fields omitted } struct节点{ set:HashSet, //省略了其他字段 } 我必须为一个trait(兼容性问题)实现一个函数,该trait需要将集合中的所有元素作为一个片段返回 我知道以下功能无法正常工作: impl Node { pub fn set_slice(&self) -> &[usize] {
struct Node {
set: HashSet<usize>,
// other fields omitted
}
struct节点{
set:HashSet,
//省略了其他字段
}
我必须为一个trait(兼容性问题)实现一个函数,该trait需要将集合中的所有元素作为一个片段返回
我知道以下功能无法正常工作:
impl Node {
pub fn set_slice(&self) -> &[usize] {
let elems: Vec<_> = self.set.iter().cloned().collect();
&elems[..]
}
}
impl节点{
pub fn set_slice(&self)->和[usize]{
让elems:Vec=self.set.iter().cloned().collect();
&元素[…]
}
}
问题是:
错误[E0597]:`elems`寿命不够长
-->src/main.rs:11:10
|
11 |和元素[…]
|^^^^^^借来的价值寿命不够长
12 | }
|-借来的价值仅在此处有效
|
注意:借用值必须在9:5对方法体上定义的匿名生存期#1有效。。。
-->src/main.rs:9:5
|
9 |/pub fn set_slice(&self)->和[usize]{
10 | |让elems:Vec=self.set.iter().cloned().collect();
11 | |和元素[…]
12 | | }
| |_____^
我知道这个要求听起来很奇怪。不管我为什么要这么做,有没有“好”的方法来实现这一点
如果可能的话,我希望保留
HashSet
容器进行O(1)查找,并且我不希望为了节省内存而引入新的结构成员 不,您的要求是100%完全不可能在安全防锈的情况下实现的
HashSet
/HashMap
没有连续的数据集合,因此无法从中获取切片
如果你能改变事情,那么你有选择 如果可以存储
Vec
,并且方法是&mut self
,则可以“呈现”哈希集的视图:
struct Node {
set: HashSet<usize>,
view: Vec<usize>,
// other fields omitted
}
impl Node {
pub fn set_slice(&mut self) -> &[usize] {
self.view.clear();
self.view.extend(self.set.iter().cloned());
&self.view
}
}
你可以:
impl节点{
pub fn set_slice impl迭代器,这在简单(基本)的方法中是不可能的
这在Box
,mut static
中是可能的,但我建议修改您的trait并返回如下示例中的内容:
您可以在trait中使用AsRef
而不是&[usize]
。或者只返回迭代器
struct Node {
set: HashSet<usize>,
}
trait SetSlice {
type Slice: AsRef<[usize]>;
fn get_slice_cloned(&self) -> Self::Slice;
}
impl SetSlice for Node {
type Slice = Vec<usize>;
fn get_slice_cloned(&self) -> Self::Slice { self.set.iter().cloned().collect() }
}
// there we use auto-impl of Iterator trait
// and return the iter.
// NOTE: we cannot use auto-impl in trait methods.
impl Node {
fn get_neat_iter(&self) -> impl Iterator<Item = &usize> { self.set.iter() }
}
fn need_slice(slice: &[usize]) {}
fn main() {
let n = Node { set: Default::default(), };
// as_ref
let all = n.get_slice_cloned();
need_slice(all.as_ref());
// iter-way
let all: Vec<_> = n.get_neat_iter().cloned().collect();
need_slice(&all);
}
struct节点{
set:HashSet,
}
性状片{
类型切片:AsRef;
fn获取切片\u克隆(&self)->self::切片;
}
节点的impl SetSlice{
类型Slice=Vec;
fn get_slice_cloned(&self)->self::slice{self.set.iter().cloned().collect()}
}
//在这里,我们使用迭代器特性的自动impl
//归还国际热核实验堆。
//注意:我们不能在trait方法中使用auto impl。
impl节点{
fn get_neat_iter(&self)->impl迭代器{self.set.iter()}
}
fn需要_切片(切片:&[usize]){}
fn main(){
设n=Node{set:Default::Default(),};
//作为参考
让all=n.获取切片克隆();
需要_切片(all.as_ref());
//iter方式
let all:Vec=n.get_neat_iter().cloned().collect();
需要_切片(&all);
}
这只是两种不同的方法。谢谢你的回答。向临时变量elems
添加生存期约束有效吗?@Yang不。我说不可能时是认真的。如果你不能更改哈希集
或特征,并且不添加字段,那么就没有解决方案。我正在尝试使用Cow
,一旦我有了就让cow=Cow::from(&slice[…])
或让Cow=Cow::from(vec)
,我如何才能取回&slice[…]
。我使用了Cow.borrow()
,但需要错误类型注释:无法解析“std::borrow:”Cow@Yang&cow[…]在这里有可能出现XY问题。考虑在使用该特性时显示更多的上下文。
impl Node {
pub fn set_slice<'a>(&'a self) -> impl Iterator<Item = &'a usize> + 'a {
self.set.iter()
}
}
struct Node {
set: HashSet<usize>,
}
trait SetSlice {
type Slice: AsRef<[usize]>;
fn get_slice_cloned(&self) -> Self::Slice;
}
impl SetSlice for Node {
type Slice = Vec<usize>;
fn get_slice_cloned(&self) -> Self::Slice { self.set.iter().cloned().collect() }
}
// there we use auto-impl of Iterator trait
// and return the iter.
// NOTE: we cannot use auto-impl in trait methods.
impl Node {
fn get_neat_iter(&self) -> impl Iterator<Item = &usize> { self.set.iter() }
}
fn need_slice(slice: &[usize]) {}
fn main() {
let n = Node { set: Default::default(), };
// as_ref
let all = n.get_slice_cloned();
need_slice(all.as_ref());
// iter-way
let all: Vec<_> = n.get_neat_iter().cloned().collect();
need_slice(&all);
}