gpt4 book ai didi

rust - 如何在 Rust Closure 中返回引用

转载 作者:行者123 更新时间:2023-12-03 11:26:00 26 4
gpt4 key购买 nike

我有以下 rust 代码无法编译。

struct Person {
name : String,
age : u8,
}


fn main() {
let p = Person{ name: "Nobody".to_string(), age : 24};

let age = |p : &Person| p.age;
let name = |p : &Person | &p.name;

println! ("name={}, age={}" , name(&p), age(&p));
}

编译器给出了以下错误信息。

   Compiling playground v0.0.1 (/playground)
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
--> src/main.rs:11:31
|
11 | let name = |p : &Person | &p.name;
| ^^^^^^^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the body at 11:16...
--> src/main.rs:11:16
|
11 | let name = |p : &Person | &p.name;
| ^^^^^^^^^^^^^^^^^^^^^^
note: ...so that reference does not outlive borrowed content
--> src/main.rs:11:31
|
11 | let name = |p : &Person | &p.name;
| ^^^^^^^
note: but, the lifetime must be valid for the expression at 2:29...
--> src/main.rs:13:5
|
13 | println! ("name={}, age={}" , name(&p), age(&p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
note: ...so type `(&&std::string::String, &u8)` of expression is valid during the expression
--> src/main.rs:13:5
|
13 | println! ("name={}, age={}" , name(&p), age(&p));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: this error originates in a macro outside of the current crate (in Nightly builds, run with -Z external-macro-backtrace for more info)

error: aborting due to previous error

我尝试为 name 闭包添加生命周期。

let name<'a> = |p : &'a Person | -> &'a String { &'a p.name };

还是编译出错

   Compiling playground v0.0.1 (/playground)
error: expected one of `:`, `;`, `=`, `@`, or `|`, found `<`
--> src/main.rs:12:13
|
12 | let name<'a> = |p : &'a Person | -> &'a String { &'a p.name };
| ^ expected one of `:`, `;`, `=`, `@`, or `|`

error: aborting due to previous error

只是想知道如何编写正确的代码。

最佳答案

另一种解决方案是为您的闭包提供显式类型。遗憾的是,您不能使用它的实际类型,但可以将其转换为函数指针。

请记住,问题在于编译器无法正确推断输出的生命周期与输入的生命周期相关(它可能是 this bug 的一个实例,但我根本不是当然)。我们可以通过使生命周期显式化来解决这个问题。

struct Person {
name: String,
age: u8,
}

fn main() {
let p = Person {
name: "Nobody".to_string(),
age: 24,
};

let age = |p: &Person| p.age;
// Our only changes are right here.
let name: for<'a> fn(&'a Person) -> &'a String = |p: &Person| &p.name;

println!("name={}, age={}", name(&p), age(&p));
}

(playground)

事实上,它可能比这稍微不那么明确。编译器可以很好地确定输入和输出的类型。这只是它遇到麻烦的生命周期。所以用 let name: for<'a> fn(&'a _) -> &'a _ = |p: &Person| &p.name; 替换该行也适用 (playground) .

关于rust - 如何在 Rust Closure 中返回引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60897823/

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