传递给函数的引用传递给函数

时间:2018-08-15 19:47:08

标签: rust

考虑以下Rust代码:

fn foo<'a, T, F, G>(x: &'a mut T, f: F, g: G)
where
    T: 'a,
    F: Fn(&'a T) -> &'a T,
    G: Fn(&'a mut T) -> &'a mut T,
{
    {
        f(x);
    }
    g(x);
}

fn main() {
    let mut x = 5;
    foo(&mut x, |a| a, |a| a);
}

这会导致编译器错误:

error[E0502]: cannot borrow `*x` as mutable because it is also borrowed as immutable
  --> src/main.rs:10:7
   |
8  |         f(x);
   |           - immutable borrow occurs here
9  |     }
10 |     g(x);
   |       ^ mutable borrow occurs here
11 | }
   | - immutable borrow ends here

我不明白为什么x的不可变借项在第11行结束。例如,f(x)在第9行的内部范围内。但是,{{1 }}没有绑定任何变量,因此我认为借用应该在第8行结束,甚至不需要内部作用域。

1 个答案:

答案 0 :(得分:4)

让我们考虑一下this example

fd_set

这是完全合法的,因为可以保证函数select()采用与fn foo<'a, T, F, G>(x: &'a mut T, mut f: F, g: G) where T: 'a, F: FnMut(&'a T) -> &'a T, G: Fn(&'a mut T) -> &'a mut T, { { f(x); } } fn main() { let mut x = 5; let mut y = std::cell::RefCell::new(&0); foo(&mut x, |a| { y.replace(&a); a }, |a| a); } 相同的生存期的引用,因此它可以存储对{{1}的引用}。但是您不能用f来调用x,因为x可能已经存储了g

如果您将x更改为:

f

(由于生命周期删除规则)等效于:

x

然后foo isn't allowed to store the reference x

fn foo<T, F, G>(x: &mut T, mut f: F, g: G)
where
    F: FnMut(&T) -> &T,
    G: Fn(&T) -> &T,

但将fn foo<'a, T, F, G>(x: &'a mut T, mut f: F, g: G) where T: 'a, F: for<'b> FnMut(&'b T) -> &'b T, G: for<'c> Fn(&'c T) -> &'c T, 称为f becomes legal