可以在 Rust 中执行块表达式的捕获吗?

Possible in Rust to perform captures for block expressions?

我指的那种事情的简单例子:

let x = 10;
if true {
    let x = 20;
}
println!("x is {}", x);

这将打印 x is 10,而不是 x is 20,并给我一个未使用的变量警告,因为 if 块中的 x 与外部的 x 不同它。有没有一种方法可以对 if 执行类似捕获的操作,以便它实际作用于包含块的 x?

我在这里想象,通过重复的 let 语句来执行阴影是可取的,但是如果它只是一个 int,这个例子会更简洁。在伪代码中,也许它更像是:

let data = get_data_from_user();
let data = initial_processing(data);
let data = further_processing(data);
if some_condition {
    let data = conditional_processing(data);
} else {
    let data = fallback_processing(data);
}

(也许答案是这是代码味道,我应该将 if some_condition 检查移到 conditional_processing 函数调用中。)

例如,对可重现示例的一种可能重写:

let mut x = 10;
if true {
    x = 20;
}

我认为这与我的想法相去甚远。

可以写

let x = 10;
let mut y = x;
if true {
    y = 20;
}
let x = y;
println!("x is {}", x);

因此 x 最终成为一个设置为 20 的非可变变量,尽管以引入一次性中间可变变量 y 为代价。但我仍然很好奇是否有可能通过让 if 块捕获并故意隐藏它之外的变量来实现这一点。

已更新(请参阅下面的原始答案)

您可能对

感兴趣
let data = get_data_from_user();
let data = initial_processing(data);
let data = further_processing(data);
let data = if some_condition {
    conditional_processing(data)
} else {
    fallback_processing(data)
};

或者如果您想为 else

保留相同的值
let x = 10;
let x = if true {
    20
} else {
    x
}

原回答

不,这不可能。

  • 您不能强制变量在定义块外可见。所以 let x = <...> 将不起作用。
  • 您不能更改不可变变量的值。所以 x = <...> 将不起作用。
  • 没有其他方法可以为变量赋值。

您可以通过重新绑定相同的变量来实现。

// first step, prepare x as mutable
let mut x = 10;
if true {
    x = 20;
}
let x = x; // new binding for x
// from now on, x is immutable

表达相同想法的更常见(或可读)方式:

let x = {
    // prepare a mutable x just inside this block
    let mut x = 10;
    if true {
       x = 20;
    }
    x // the result of this whole block
};
// in this scope, x is immutable

这两个结构的共同点是你开始 使用可变绑定来初始化多个值 步骤,然后当它完成时,你切换到一个不可变的绑定 相同的值,以防止意外 变异它。