使用 FnMut 了解 Iter

Roh*_*rma 3 rust

由于Iter 的“所有”fn 采用 FnMut 类型,是否可以在检查条件和短路时更新元素?虽然我知道这是不应该的,但是是什么阻止它更新值呢?

fn main() {
   let a = ["as", "zz"];

    let mut iter = a.iter();
    iter.all(|& (mut x)| {x = "cc"; true});

    for z in a.iter(){
        println!("{z}");
    }
}
Run Code Online (Sandbox Code Playgroud)

上面打印

as
zz
Run Code Online (Sandbox Code Playgroud)

在上述情况下,为什么设置“x = cc”不起作用?或者为什么 Iter “all” 方法采用 FnMut 类型的 F 而不是 Fn 当它不应该变异而只验证条件时

Jmb*_*Jmb 5

x = "cc"不会更改 引用的值x,而是更改引用本身(即使其引用另一个值),如以下示例所示:

fn main() {
   let a = ["as", "zz"];

    let mut iter = a.iter();
    iter.all(|&(mut x)| {
        println!("before: {:?}", x as *const _);
        x = "cc";
        println!("after: {:?}", x as *const _); 
        true});

    for z in a.iter(){
        println!("{z}");
    }
}
Run Code Online (Sandbox Code Playgroud)

操场

请注意,这与闭包为 的事实无关FnMut,这仅意味着它可能会更改任何捕获的值,如下所示:

fn main() {
   let a = ["as", "zz"];

    let mut count = 0;
    let mut iter = a.iter();
    iter.all(|&_x| {
        count += 1;    // This is possible because the closure is `FnMut`
        true});
    println!("Count: {count}");
    
    for z in a.iter(){
        println!("{z}");
    }
}
Run Code Online (Sandbox Code Playgroud)

操场