rust - 为什么我可以返回对函数拥有值的引用?
问题描述
在The Rust Programming Language的第 19.2 章中,以下示例编译时没有任何错误。我从issue #1834发现有一个新的生命周期省略规则隐含地使's
比'c
.
虽然我找不到这个新的省略规则的详细解释,但我想它不仅仅是更长、更明确的约束的隐式版本:<'c, 's: 'c>
. 但是我认为我的困惑可能不是关于这个新的省略规则,但我当然可能是错的。
我的理解是,它parse_context
拥有所有权,context
因为它没有被借用,而是实际上转移到了函数中。仅此一点就意味着 的生命周期context
应该与它所拥有的函数的生命周期相匹配,而不管我们在 和 中定义的生命周期和Context
约束Parser
。
基于这些定义,对我来说,context
超过临时的部分Parser
是完全有意义的(毕竟,我们定义了更长的生命周期),但是在结束时超出范围&str
时引用不会被删除的部分,我仍然可以安全地退货——让我很困惑。context
parse_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);
}
}
解决方案
您没有返回对函数拥有值的引用。您正在返回传入的引用的副本。
您的函数是身份函数的详细版本:
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()
}
也可以看看:
虽然我找不到这个新的省略规则的详细解释,
推荐阅读
- rust - 使用 mod 关键字访问 rust 中的子目录
- django - 在 django 中修改 request.query_params
- matlab - 从数据集中提取最小值的函数 [MATLAB]
- .net-core - 如何阻止 HttpRequestMessage 将 %3A 取消编码为请求 URI 中的冒号(asp.net 核心)
- javascript - JavaScript - Convert bytes into float in a clean way
- javascript - Why my effect is running serveral times after action is called?
- go - 为什么我的代码死锁以及如何修复它
- node.js - Electron shell.openExternal 无法打开一些 .lnk 快捷方式
- c# - EF 6.3:它为从 DataAnnotation 更改为 FluentAPI 创建了相同的迁移
- python - Extract value in dict