< 返回版块

cyh0 发表于 2021-12-08 21:49

fn main() {
    let a = A {
        x: "xxx".to_string(),
    };
    let a1 @ a2 @ A { x } = a; // line1
    // 问题: line1 相当于 line2加line3加line4么?
    let x = a.x;        // line2
    let a2 = a;         // line3
    let a1 = a2;        // line4

}
struct A {
    x: String,
}

评论区

写评论
苦瓜小仔 2021-12-09 12:51

从这段代码正常运行的角度看,是的

fn main() {
    let m @ matrix @ Matrix { row_len, .. } = Default::default();
    dbg!(row_len, matrix, m);
}

#[derive(Clone, Copy, Debug, Default)]
struct Matrix {
    row_len: usize,
}

P.S. 如果 Matrix 没有实现 Copy trait,在中间(看作 pattern 侧)依然是被移走,无法 binding。

--
👇
cyh0: 感谢,我想了解@的用法,代码本身的确是错的,现在还有一个连续多个@的用法,

    let matrix1 @ matrix2 @ Matrix { .. } = get_matrix();
    // 这种情况,要求Matrix实现copy trait,我理解没问题吧。

--
👇
苦瓜小仔

作者 cyh0 2021-12-09 10:52

感谢,我想了解@的用法,代码本身的确是错的,现在还有一个连续多个@的用法,

    let matrix1 @ matrix2 @ Matrix { .. } = get_matrix();
    // 这种情况,要求Matrix实现copy trait,我理解没问题吧。

--
👇
苦瓜小仔

苦瓜小仔 2021-12-09 01:08

不清楚你要干嘛。暂且认为你在研究 1.56 中的新特性吧:https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html#new-bindings-in-binding--pattern

改自上述官网的例子:

#![allow(unused)]
fn main() {
    // 一步到位:同时拥有 row_len 和 matrix 两个数据
    let matrix @ Matrix { row_len, .. } = get_matrix();

    // 从生成的实例中,把字段复制出来。
    let matrix = get_matrix(); // step 1 拥有 matrix 数据
    let row_len = matrix.row_len; // step 2 拥有 row_len 数据

    // 从生成的实例中,解构出来。
    let matrix = get_matrix(); // step 1 拥有 matrix 数据
    let Matrix { row_len, .. } = matrix; // step 2 拥有 row_len 数据,丢弃 matrix 数据

    // 从生成的实例中,解构出来。重新生成一个实例。
    let Matrix { row_len, .. } = get_matrix(); // step 1 拥有 row_len 数据
    let matrix = get_matrix(); // step 2 拥有 matrix 数据
}

struct Matrix {
    data: Vec<f64>,
    row_len: usize,
}

fn get_matrix() -> Matrix {
    Matrix {
        data: vec![],
        row_len: 0,
    }
}

针对结构体的 binding @ pattern 解决了什么问题呢?

在一个语句里面,在结构体赋值的同时,把结构体内部的实现了 Copy trait 类型的字段数据提取出来。

这很符合 Rust 模式匹配(简洁而强大),与 match 下的 binding @ pattern 思路一脉相承。

而你的例子根本不需要这种 @ 模式匹配,因为 String 没有实现 Copy trait,所以它在提取(解构)的时候 直接被移走,使实例 a 不存在了——因为你不可能在移走一个字段数据的情况下继续使用完整的结构体(实例)。

1 共 3 条评论, 1 页