【问题标题】:Rust Destructuring struct reference vs Destructuring structRust 解构结构引用与解构结构
【发布时间】:2021-02-25 06:08:27
【问题描述】:

以下代码有效

#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32
}

fn area(shape: &Rectangle) -> u32 {
    let Rectangle{width, height} = shape;
    width * height
}

fn main() {
    let rec1 = Rectangle {width: 5, height: 10};
    println!("Area {}", area(&rec1));
    println!("Rec {:?}", rec1);
}

但是用取消引用引用*&Shape 替换对结构&Shape 的引用也可以(例如let Rectangle{width, height} = shape; --> let Rectangle{width, height} = *shape;)。

我不知道为什么两者都有效,破坏时是否有一些隐式取消引用?我虽然&Shape 引用仅指向Shape 在内存中的位置,而*&Shape 是Shape 本身。 width 和 height 是 struct Rectangle 的属性,而不是引用 &Rectangle。

【问题讨论】:

  • 你不是在制作一个新的 Rectangle(称为 rec1),它是 shape 的副本,而不是解构吗?如果你想解构你需要使用匹配,我认为。见Rust by Example。
  • @hkBst let 也执行模式匹配,但只允许 irrefutable 模式。代码确实解构了shape,这不是问题。

标签: rust


【解决方案1】:

我不知道为什么两者都有效,销毁时是否有一些隐式取消引用?

这是 2018 版 match ergonomics 的一个(方便但令人困惑的)结果:当匹配引用类型时,编译器将隐式添加引用并取消引用,所以事情是正确的。

area 中发生的情况是 width 和 height 是 &u32 而不是 u32,编译器有效地将您的代码解释为:

let &Rectangle{ ref width, ref height } = shape;

如果你没有使用像 rust-analyzer 这样可以直接在你的编辑器中显示这些信息的东西,一个常见的技巧是写这样的东西:

let x: () = var

编译错误会告诉你var的类型是什么(除非是())。

我虽然 &Shape 引用仅指向 Shape 在内存中的位置,而 *&Shape 是 Shape 本身。

确实如此,但是在 pattern 的上下文中,这并不一定意味着结构被移动。这里因为Rectangle 的字段都是Copy,编译器可以解构“拥有”结构而不需要移动它,它可以复制字段。这本质上就是一个简单的属性访问要做的事情(shape.width 是 u32)。

【讨论】:

    猜你喜欢
    • 2022-01-11
    • 2022-01-15
    • 2015-07-13
    • 1970-01-01
    • 2021-07-12
    • 2021-08-23
    • 2019-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多