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);
}