Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 为什么HashMap有iter_mut(),而HashSet没有';T_Rust_Standard Library_Idioms - Fatal编程技术网

Rust 为什么HashMap有iter_mut(),而HashSet没有';T

Rust 为什么HashMap有iter_mut(),而HashSet没有';T,rust,standard-library,idioms,Rust,Standard Library,Idioms,提供iter_mut功能但不生锈的设计原理是什么 自己动手(假设可以做到这一点)会是失礼吗 拥有一个可以缓解导致 以前的X借用发生在此处;不变的借来阻止 X的后续移动或可变借用,直到借用结束 例子 这并不能说明为什么参数的传递方式是这样的。有一个简短的评论解释了痛点: use std::collections::HashSet; fn derp(v: i32, unprocessed: &mut HashSet<i32>) { if unprocessed.cont

提供
iter_mut
功能但不生锈的设计原理是什么

自己动手(假设可以做到这一点)会是失礼吗

拥有一个可以缓解导致

以前的
X
借用发生在此处;不变的借来阻止
X
的后续移动或可变借用,直到借用结束

例子 这并不能说明为什么参数的传递方式是这样的。有一个简短的评论解释了痛点:

use std::collections::HashSet;

fn derp(v: i32, unprocessed: &mut HashSet<i32>) {
    if unprocessed.contains(&v) {

        // Pretend that v has been processed
        unprocessed.remove(&v);
    }   
}

fn herp(v: i32) {
    let mut unprocessed: HashSet<i32> = HashSet::new();
    unprocessed.insert(v);

    // I need to iterate over the unprocessed values
    while let Some(u) = unprocessed.iter().next() {

        // And them pass them mutably to another function
        // as I will process the values inside derp and
        // remove them from the set.
        //
        // This is an extremely convoluted example but
        // I need for derp to be a separate function
        // as I will employ recursion there, as it is
        // much more succinct than an iterative version.
        derp(*u, &mut unprocessed);
    }   
}

fn main() {
    println!("Hello, world!");
    herp(10);
}
是一种不变的借用,因此

derp(*u, &mut unprocessed);
这是不可能的,因为未经加工的产品不能相互借用。不可变的借用直到while循环结束才结束


我曾经尝试过使用,但最终却试图通过各种排列的赋值、大括号来愚弄借阅检查器,但由于预期表达式的耦合,问题仍然存在。

您必须思考实际情况。您从中获取的值仅在值部分是可变的:
(&key,&mut val)
,(
(&a K,&a mut V)


HashSet
基本上是一个
HashMap
,因此实际值就是键,如果要修改键,则必须更新键的散列,或者如果
HashSet
包含
Copy
类型,例如
i32
,则会得到无效的
HashMap

,您可以在值的副本上工作,以便尽早在
HashSet
上释放借用。为此,需要消除
while let
表达式中绑定的所有借用。在原始代码中,
u
的类型为
&i32
,它一直从
未处理的
借用,直到循环结束。如果我们将模式更改为
Some(&u)
,那么
u
属于
i32
类型,它不借用任何东西,因此我们可以随意使用
未处理的

fn herp(v: i32) {
    let mut unprocessed: HashSet<i32> = HashSet::new();
    unprocessed.insert(v);

    while let Some(&u) = unprocessed.iter().next() {
        derp(u, &mut unprocessed);
    }   
}

您建议如何用另一个集合替换
哈希集
。我只需要
包含
删除
插入
。带有自制
的向量包含
?以及一种通过查找其索引或其他方法来删除特定对象的方法。@FilipAllberg您能给出一个代码示例,说明您实际想做什么吗?在原始的postNote中提供了一个浓缩的示例,
,而let some(u)=unprocessed.iter().next()
相当于u-in&unprocessed
,这里还有另一个问题:在迭代
未处理的
时,不能可变地借用它/保留对它的引用。为什么不简单地让循环使用未处理的
并简化程序逻辑呢?如果类型不可复制,那么让循环使用集合并让
derp
而不是将项目插入新的
HashSet
True,但是,如果
derp
将集合用于除删除当前项以外的其他目的,例如,如果一个项的处理取决于剩下哪些项需要处理(问题中的
derp
的实现仅用于演示目的,据我所知)。
fn herp(v: i32) {
    let mut unprocessed: HashSet<i32> = HashSet::new();
    unprocessed.insert(v);

    while let Some(&u) = unprocessed.iter().next() {
        derp(u, &mut unprocessed);
    }   
}
use std::collections::HashSet;
use std::rc::Rc;

fn derp(v: &i32, unprocessed: &mut HashSet<Rc<i32>>) {
    if unprocessed.contains(v) {
        unprocessed.remove(v);
    }   
}

fn herp(v: Rc<i32>) {
    let mut unprocessed: HashSet<Rc<i32>> = HashSet::new();
    unprocessed.insert(v);

    while let Some(u) = unprocessed.iter().cloned().next() {
        // If you don't use u afterwards,
        // you could also pass if by value to derp.
        derp(&u, &mut unprocessed);
    }   
}

fn main() {
    println!("Hello, world!");
    herp(Rc::new(10));
}