我有这个代码:
fn f(x: &mut (i32, i32)) -> &(i32, i32) {
x.1 = x.1 + 11;
x.0 = x.0 * 10;
x
}
我会比较喜欢:
fn f((x, y) as t: &mut (i32, i32)) -> &(i32, i32) {
x = x + 11;
y = y * 10;
t
}
可以实现这样的可读性吗?
可以实现这样的可读性吗?
不,不是在当前的Rust或计划的未来。类似于您想要的语法:
fn f(t @ &mut (ref x, ref y): &mut (i32, i32)) -> &(i32, i32)
但是,不允许:
error[E0007]: cannot bind by-move with sub-bindings
--> src/main.rs:3:6
|
3 | fn f(t @ &mut (ref x, ref y): &mut (i32, i32)) -> &(i32, i32) {
| ^^^^^^^^^^^^^^^^^^^^^^^ binds an already bound by-move value by moving it
error[E0303]: pattern bindings are not allowed after an `@`
--> src/main.rs:3:16
|
3 | fn f(t @ &mut (ref x, ref y): &mut (i32, i32)) -> &(i32, i32) {
| ^^^^^ not allowed after `@`
error[E0303]: pattern bindings are not allowed after an `@`
--> src/main.rs:3:23
|
3 | fn f(t @ &mut (ref x, ref y): &mut (i32, i32)) -> &(i32, i32) {
| ^^^^^ not allowed after `@`
这种代码的一个棘手的方面是你有可变的别名 - 你可以通过t.0
和x
改变相同的值。这在Rust中是不允许的。
很有可能,备受期待的非词汇生命周期(NLL)可能允许编译器更好地推理这些案例,但我没有听到人们采取这个具体方面。
如果您愿意灵活,有一些选择:
fn f(t: &mut (i32, i32)) -> &(i32, i32) {
{
let &mut (ref mut x, ref mut y) = t;
*x = *x + 11;
*y = *y * 10;
}
t
}
在夜间Rust中,这可以简化:
#![feature(match_default_bindings)]
fn f(t: &mut (i32, i32)) -> &(i32, i32) {
{
let (x, y) = t;
*x = *x + 11;
*y = *y * 10;
}
t
}
据我了解,这两种情况都应该由NLL改进。
由于您正在获取并返回相同的值引用,因此您可以停止返回它:
fn f(&mut (ref mut x, ref mut y): &mut (i32, i32)) {
*x = *x + 11;
*y = *y * 10;
}
在夜间Rust中同样可以改进:
#![feature(match_default_bindings)]
fn f((x, y): &mut (i32, i32)) {
*x = *x + 11;
*y = *y * 10;
}