可以在 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
这两个结构的共同点是你开始
使用可变绑定来初始化多个值
步骤,然后当它完成时,你切换到一个不可变的绑定
相同的值,以防止意外
变异它。
我指的那种事情的简单例子:
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
这两个结构的共同点是你开始 使用可变绑定来初始化多个值 步骤,然后当它完成时,你切换到一个不可变的绑定 相同的值,以防止意外 变异它。