gpt4 book ai didi

struct - 为什么在 Rust 中允许返回当前函数拥有的引用?

转载 作者:行者123 更新时间:2023-11-29 07:56:48 25 4
gpt4 key购买 nike

我正在学习 Rust 的生命周期/所有权概念,并想解释 Rust (rustc 1.37.0) 中的以下行为。

对于这样的程序:

#[derive(Debug)]
struct Book {
price: i32,
}

fn main() {
let book1 = Book {price: 12};
let cheaper_book = choose_cheaper(&book1);
println!("{:?}", cheaper_book);
}

fn choose_cheaper(b1: &Book) -> &Book {
if b1.price < 15 {
b1
} else {
let cheapest_book = Book {price: 0};
&cheapest_book
}
}

使用rust 报告:

17 |   &cheapest_book
| ^^^^^^^^^^^^^^ returns a reference to data owned by the current function

我能理解这个错误,这是因为变量 cheapest_book 是价格为 0 的书的所有者,它会在这个函数结束时被丢弃,所以返回的引用将变成之后无效。但是如果我将 choose_cheaper 函数更改为:

,我很难解释为什么允许以下内容:
fn choose_cheaper(b1: &Book) -> &Book {
if b1.price < 15 {
b1
} else {
let cheapest_book = &Book {price: 0};
cheapest_book
}
}

有人能给我一些启发吗?谢谢。

最佳答案

在行let cheapest_book = &Book {price: 0}; , Book 不是 Book 的"new"实例类型。每次调用此函数时,它都会返回对 Book相同 实例的引用。类型,它将存储在可执行文件的只读数据部分(或者,从技术上讲,数据部分,如果它包含 CellAtomicUsize 或类似内容)。

在这种情况下,我们可以将代码“扩展”为更明确的内容:

static GLOBAL_BOOK: Book = Book { price: 0 };

fn choose_cheaper<'a>(b1: &'a Book) -> &'a Book {
if b1.price < 15 {
b1
} else {
let cheapest_book = &GLOBAL_BOOK;
cheapest_book
}
}

请注意对 GLOBAL_BOOK 的引用实际上可能是 &'static Book ,但是&'a Book是它的父类(super class)型,因此可以将静态引用作为 'a 返回引用。

如果这看起来很奇怪,请考虑这正是字符串文字所发生的事情;他们只是没有明确的 &字符:在let foo = "string!";之后, foo&'static str引用可执行文件的只读部分中的某些数据,而不是本地对象。所以你也可以写return "string!";在返回 &'a str 的函数中对于任何 'a .

rust 是否会进行这种转换的规则是每当你“构造”一个​​对象时(使用元组语法,或结构或枚举或联合初始化语法,或数字或字符串文字,或它们的任何组合 - 不是 函数调用 new() 或任何其他函数)在 & 后面,它们将变成匿名静态。所以其实&&1_u32'static引用静态 'static引用静态 u32 .

关于struct - 为什么在 Rust 中允许返回当前函数拥有的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57815212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com