繁体   English   中英

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

[英]Why returning a reference owned by the current function is allowed in Rust?

我正在学习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
    }
}

锈报告:

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

而且我可以理解此错误,这是因为变量cheapest_book是价格为0的Book的所有者,并且它将在此函数结束时删除,因此返回的引用在此之后将变为无效。 但是,对于我来说,很难解释为什么如果将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类型的“新”实例。 每次调用此函数时,它都会返回对相同 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&'a Book的超类型,因此可以将静态引用当作是'a引用来返回。

如果这看起来很奇怪,请考虑一下这正是字符串文字所发生的; 它们只是没有显式&字符: let foo = "string!"; foo&'static str引用可执行文件的只读部分中的某些数据,而不是本地对象。 这样您还可以编写return "string!"; 在函数返回&'a str为任何'a

生锈是否进行此转换的规则是您“构造”对象时(使用元组语法,结构或枚举或联合初始化语法,数字或字符串文字或它们的任意组合- 而不是new()函数调用或&后面的任何其他函数),它们将成为匿名静态变量。 所以其实&&1_u32'static参考静态'static参考静态u32

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM