gpt4 book ai didi

rust - 为什么 Rust 编译器不能推断出一个参数比另一个参数长寿?

转载 作者:行者123 更新时间:2023-12-05 03:17:43 25 4
gpt4 key购买 nike

我有以下代码:

struct Solver<'a> {
guesses: Vec<&'a str>,
}

impl<'a> Solver<'a> {
fn register_guess(&mut self, guess: &'a str) {
self.guesses.push(guess);
}
}

fn foo(mut solver: Solver, guess: &str) {
solver.register_guess(guess)
}

它不编译:

   |
11 | fn foo(mut solver: Solver, guess: &str) {
| ---------- - let's call the lifetime of this reference `'1`
| |
| has type `Solver<'2>`
12 | solver.register_guess(guess)
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`

错误消息说参数 guess必须比 solver 长寿.对我来说很明显这是真的:solver 的生命周期在函数结束时结束,guess 的生命周期没有。这似乎是编译器应该能够推断并编译而不会出错的东西。

为什么不是这样呢?这段代码是否真的有一些方法 solver活得更久guess ?或者只是编译器根本不尝试进行这种推理?

我知道如何修复它 --- 将函数更改为 fn foo<'a>(mut solver: Solver<'a>, guess: &'a str) --- 但我在问为什么我必须这样做。

最佳答案

同时 solver本身活不过guess ,它所指的一生很好。例如,假设调用 foo()Solver<'static> .那种求解器期望猜测是 &'static str并可能存储 guess 引用的数据在一个全局变量中。 (请记住,编译器在借用检查 register_guess() 时不考虑 foo() 做了什么,它只考虑它的签名。)

更一般地说,Solver<'a>可能包含对 'a 的引用超过 solver 的数据本身。没有什么能阻止 register_guess()从将 guess 的内容存储在此类引用中。如果guess不能保证至少活到'a。 , 然后 foo()简直是不健全。例如,采用 Solver 的替代定义:

struct Solver<'a> {
guesses: &'a mut Vec<&'a str>,
}

未更改 register_guess() 的签名, foo()将允许这样的不合理代码:

fn main() {
let mut guesses = vec![];
let solver = Solver { guesses: &mut guesses };
{
let guess = "foo".to_string();
// stores temporary "foo" to guesses, which outlives it
foo(solver, guess.as_str());
}
println!("{}", guesses[0]); // UB: use after free
}

关于rust - 为什么 Rust 编译器不能推断出一个参数比另一个参数长寿?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74008920/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com