首页 > 解决方案 > 为什么我可以返回对函数拥有值的引用?

问题描述

The Rust Programming Language的第 19.2 章中,以下示例编译时没有任何错误。我从issue #1834发现有一个新的生命周期省略规则隐含地使's'c.

虽然我找不到这个新的省略规则的详细解释,但我想它不仅仅是更长、更明确的约束的隐式版本:<'c, 's: 'c>. 但是我认为我的困惑可能不是关于这个新的省略规则,但我当然可能是错的。

我的理解是,它parse_context拥有所有权,context因为它没有被借用,而是实际上转移到了函数中。仅此一点就意味着 的生命周期context应该与它所拥有的函数的生命周期相匹配,而不管我们在 和 中定义的生命周期和Context约束Parser

基于这些定义,对我来说,context超过临时的部分Parser是完全有意义的(毕竟,我们定义了更长的生命周期),但是在结束时超出范围&str时引用不会被删除的部分,我仍然可以安全地退货——让我很困惑。contextparse_context

我错过了什么?编译器如何推断返回的生命周期&str

更新示例

struct Context<'s>(&'s str);

struct Parser<'c, 's>
{
    context: &'c Context<'s>,
}

impl<'c, 's> Parser<'c, 's>
{
    fn parse(&self) -> Result<(), &'s str>
    {
        Err(self.context.0)
    }
}

fn parse_context(context: Context) -> Result<(), &str>
{
    Parser { context: &context }.parse()
}

fn main()
{
    let mut s = String::new();
    s += "Avail";
    s += "able?";
    if let Err(text) = parse_context(Context(&s))
    {
        println!("{}", text);
    }
}

标签: rustlifetimeownership

解决方案


没有返回对函数拥有值的引用。您正在返回传入的引用的副本。

您的函数是身份函数的详细版本:

fn parse_context(s: &str) -> &str {
    s
}

在您的真实代码中,您引用一个包含字符串切片的结构,然后引用另一个字符串切片,但所有这些引用都被丢弃了。

例如,在 中有一个不需要的引用parse

fn parse(&self) -> Result<(), &'s str> {
    Err( self.context.0)
    //  ^ no & needed
}

此外,如果您启用更多 lints,您将被迫为您的函数签名添加更多生命周期,这可能会使事情更清楚:

#![deny(rust_2018_idioms)]

fn parse_context(context: Context<'_>) -> Result<(), &'_ str> {
    Parser { context: &context }.parse()
}

也可以看看:

虽然我找不到这个新的省略规则的详细解释,

T: 'a版本指南中的结构推断。


推荐阅读