如何从HashSet形成切片?

All*_*Lee 2 lifetime rust

结构定义为:

struct Node {
    set: HashSet<usize>,
    // other fields omitted
}
Run Code Online (Sandbox Code Playgroud)

必须为特征(兼容性问题)实现一个函数,该函数需要将集合中的所有元素作为切片返回。

我知道以下功能将无法正常工作:

impl Node {
    pub fn set_slice(&self) -> &[usize] {
        let elems: Vec<_> = self.set.iter().cloned().collect();
        &elems[..]
    }
}
Run Code Online (Sandbox Code Playgroud)

问题是:

struct Node {
    set: HashSet<usize>,
    // other fields omitted
}
Run Code Online (Sandbox Code Playgroud)

我知道这个要求听起来很奇怪。尽管为什么我必须这样做,是否有任何“好的”方式来实现这一目标?

如果有可能,我想保留该HashSet容器以进行O(1)查找,并且我不想引入新的struct成员以节省内存。

She*_*ter 5

不,在安全的Rust中完全不可能满足您的要求。

HashSet/ HashMap没有一个连续的数据集,从而有没有办法从他们那里得到一个切片。


如果可以更改,那么您可以选择。

HashSet如果可以存储,则可以“呈现”视图,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
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以返回Cow借入或拥有的:

use std::borrow::Cow;

impl Node {
    pub fn set_slice(&self) -> Cow<[usize]> {
        self.set.iter().cloned().collect::<Vec<_>>().into()
    }
}
Run Code Online (Sandbox Code Playgroud)

您可以在值上返回一个迭代器

impl Node {
    pub fn set_slice<'a>(&'a self) -> impl Iterator<Item = &'a usize> + 'a {
        self.set.iter()
    }
}
Run Code Online (Sandbox Code Playgroud)

可能是 一箱是采用紧密封装Vec作为其后备存储器,然后可能会暴露一个切片。

  • @杨没有 当我说不可能时,我是说真的。如果您不能更改`HashSet`或trait并且不添加字段,则没有解决方案。 (2认同)