微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

生命周期参数和借用如何在函数签名中交互

如何解决生命周期参数和借用如何在函数签名中交互

假设我在 Rust 中有一个具有以下签名的函数

! Sorry,but C:\Users\AP\AppData\Local\Programs\MiKTeX\miktex\bin\x64\pdflatex.exe did not succeed.

! The log file hopefully contains the information to get MiKTeX going again:

!   C:\Users\AP\AppData\Local\MiKTeX\miktex\log\pdflatex.log

Error: LaTeX Failed to compile new-report.tex. See https://yihui.org/tinytex/r/#debugging for debugging tips. See c2089682-report.log for more info.
In addition: Warning message:
In has_crop_tools() : 
Tool(s) not installed or not in PATH: ghostcript
-> As a result,figure cropping will be disabled.
Execution halted

假设我执行以下操作:

fn f<'a>(x: &'a i32) -> &'a i32;

在这种情况下,Rust 借用检查器认为 let x = 0; let y = f(&x); 借用 y。为什么?比“因为你在参数类型和返回类型中使用了相同的生命周期参数”更深层次的原因是什么。

解决方法

函数签名

fn f<'a>(x: &'a i32) -> &'a i32;

表示 f 返回的值是对 x 参数所指内容的引用,因此它不能超过它。例如,这行不通:

// Compile error
let y = {
    let x = 0;
    f(&x)

    // x is dropped here
};

// Here y still "exists",but x doesn't (y outlives x)

针对您的具体问题:

假设我执行以下操作:

let x = 0;
let y = f(&x);

在这种情况下,Rust 借用检查器认为 y 借用了 x。为什么?

答案是因为 f 的函数签名告诉了它。举个例子,假设我们把签名改成这样:

fn f<'a,'b>(x: &'a i32,z: &'b i32) -> &'a i32;

然后我们像这样调用 f

let x = 0;
let z = 1;
let y = f(&x,&z);

在上面的代码中,y 借用了 x,但不是 z。这是因为 f 的返回值具有与 'a 的生命周期相同的 x 生命周期。

,

使用 Rustonomicon 中的语法,我们可以详细说明第二个片段

let x: i32 = 0;
'a: { // definition of a lifetime (not real syntax)
    let y: &'a i32 = f::<'a>(&'a x) // &'a x is also not real,though interestingly rustc recognizes it
}

生命周期 'a 是由编译器引入的,因为您编写了一个 &,它需要知道借用将持续多长时间(请注意,您无法手动指定借用的生命周期)。函数的类型也意味着 y 在其类型中有 'a。编译器需要弄清楚 'a 在哪里开始和结束。规则是 'a 必须在您执行借用之前立即开始,在 x 期间不能移动 'a(因为它已借用),并且 y 不能在之后使用'a(因为它的类型是这样说的)。如果编译器可以为 'a 选择开始点和结束点以便规则成立,那么它就会编译。如果不能,那就是错误。 xy 之间没有直接关系;它经历了他们都与之交互的生命周期 'a。例如。你不能移动x然后阅读*y,因为'a必须在你移动x之前和你阅读*y之后结束,但这样的时间不会存在。 TL;DR 将借用检查视为生命周期推断。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?