【问题标题】:Destructure immutable reference and bind mutably in parameter list解构不可变引用并在参数列表中可变绑定
【发布时间】:2016-06-21 16:12:03
【问题描述】:

我想解构对Copy-type 的引用并可变地绑定结果值。 注意:是的,我想创建给定参数的副本并改变该副本。这有效:

fn foo(a: &u64) {
    let mut a = *a;
    mutate(&mut a);
}

但我想通过在参数列表中解构来做到这一点。当我像这样解构时:

fn foo(&a: &u64) {
    mutate(&mut a);
}

Rust(可以理解)抱怨:

<anon>:3:17: 3:18 error: cannot borrow immutable local variable `a` as mutable
<anon>:3     mutate(&mut a);
                         ^
<anon>:1:9: 1:10 help: to make the local variable mutable, use `mut` as shown:
<anon>:  fn foo(&mut a: &u64) {

但是编译器建议的解决方案不起作用!

<anon>:1:8: 1:14 error: mismatched types:
 expected `&u64`,
    found `&mut _`
(values differ in mutability) [E0308]
<anon>:1 fn foo(&mut a: &u64) {
                ^~~~~~

如何做我想做的事?

【问题讨论】:

  • 感觉fn foo(mut &amp;a: &amp;u64) 应该可以工作,但它没有。
  • @Shepmaster 为什么它应该起作用? mut 适用于 names,而不是整个模式。您没有使引用可变,而是使 a 可变。
  • @delnan 我承认没有彻底考虑所有潜在的途径。也许它是 bad-ole-C-thinking - 用 &amp; 解构然后使结果可变。这就是为什么我发表评论而不是在答案中真正表现出我的无知^_^。
  • 我认为这是不可能的。在这种情况下,您使用的是 Copy 类型,因此您可以只使用 mut a: u64 而不是引用。然后,无论何时调用该函数,编译器都会为您生成一个可变副本。

标签: rust


【解决方案1】:

我认为你做不到。虽然模式可以解构数据(即,为部分数据引入绑定),并且绑定可以标记为可变,但在解构引用的情况下似乎没有办法将两者结合起来,即使其他组合也有效:

struct X(i32);
let it = X(5);
let X(mut inside) = it;
inside = 1;

这可能只是一个边缘情况,其他语法选择没有很好的可能性。如您所见,&amp;mut x 已被使用,并且模式不支持使用括号消除歧义。

这不是一个大问题,因为在模式之外有几种方法可以做同样的事情:

  1. 不要在模式中使绑定可变,然后再创建一个新的可变绑定 (let mut x = x;)
  2. 不要从 &dash; 开始解构因为你可以说let mut x = *reference;

试图在参数列表中过于聪明无论如何都会损害可读性,恕我直言。

【讨论】:

    【解决方案2】:

    这似乎适用于 Rust 游乐场:

    fn foo(mut a: &mut u64) {
        mutate(a);
    }
    

    简短的回答是您需要接受一个可变参数,该参数具有对u64 的可变引用的类型。我无法提供更好的答案,我还在学习中。

    在这里您可以看到一个工作示例:Rust Playground

    我不能 100% 确定我是否理解您的要求,但值得一试。

    【讨论】:

    • 在您的代码中,a 的类型不同(&amp;mut u64&amp;u64)。
    • 确实如此,但这是解决问题的一种方法。因为我不确定他们想要一个可变引用还是一个可变值。
    • 问题已经得到澄清。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-16
    • 1970-01-01
    • 1970-01-01
    • 2012-11-13
    • 2014-11-09
    • 2013-02-08
    相关资源
    最近更新 更多