如何解决生命周期参数和借用如何在函数签名中交互
! 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
选择开始点和结束点以便规则成立,那么它就会编译。如果不能,那就是错误。 x
和 y
之间没有直接关系;它经历了他们都与之交互的生命周期 'a
。例如。你不能移动x
然后阅读*y
,因为'a
必须在你移动x
之前和你阅读*y
之后结束,但这样的时间不会存在。 TL;DR 将借用检查视为生命周期推断。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。