Rust函数参数类型不匹配求助:生命周期相关代码报错
Hey there! Let's work through your Rust code issues step by step—you've got two main things going on here: a hidden lifecycle problem, and the function type mismatch error you're seeing.
First, let's unpack the core issues in your code snippet:
1. The Hidden Lifecycle Bug
In your main function, you're creating &String::from("Davide")—this is a reference to a temporary String that gets destroyed immediately after the line runs. That means your App struct is holding a dangling reference, which Rust's borrow checker will reject outright. This is a common gotcha when working with references in Rust.
2. Function Type Mismatch
Your validator functions are meant to chain together (passing a closure from one to the next), but their signatures are incomplete and likely misaligned. Let's fix both problems with concrete examples.
Fix Option 1: Let App Own the String (Simplest Approach)
The easiest way to avoid lifecycle headaches here is to have App take ownership of the String instead of holding a reference. This removes the need for lifecycle annotations entirely:
struct App { name: String, } impl App { fn run(self) { // Chain validators and execute the final closure with `self` let result = App::validator_1(App::validator_2(App::box_command()))(self); println!("Validation result: {}", result); } // Validator 1 wraps the next closure in additional logic fn validator_1(next: Box<dyn Fn(App) -> bool>) -> Box<dyn Fn(App) -> bool> { Box::new(move |app| { println!("Running validator 1 for {}", app.name); next(app) }) } // Validator 2 does the same fn validator_2(next: Box<dyn Fn(App) -> bool>) -> Box<dyn Fn(App) -> bool> { Box::new(move |app| { println!("Running validator 2 for {}", app.name); next(app) }) } // Base command that returns the final validation logic fn box_command() -> Box<dyn Fn(App) -> bool> { Box::new(|app| { println!("Executing core command for {}", app.name); true // Replace with actual validation logic }) } } fn main() { let app = App { name: String::from("Davide"), }; app.run(); }
Fix Option 2: Use References (If You Need to Avoid Ownership)
If you really need App to hold a reference instead of owning the string, you need to ensure the referenced string lives longer than App. We'll also use &str (a more flexible string reference type) instead of &String:
struct App<'a> { name: &'a str, } impl<'a> App<'a> { fn run(self) { let result = App::validator_1(App::validator_2(App::box_command()))(self); println!("Validation result: {}", result); } fn validator_1(next: Box<dyn Fn(App<'a>) -> bool>) -> Box<dyn Fn(App<'a>) -> bool> { Box::new(move |app| { println!("Running validator 1 for {}", app.name); next(app) }) } fn validator_2(next: Box<dyn Fn(App<'a>) -> bool>) -> Box<dyn Fn(App<'a>) -> bool> { Box::new(move |app| { println!("Running validator 2 for {}", app.name); next(app) }) } fn box_command() -> Box<dyn Fn(App<'a>) -> bool> { Box::new(|app| { println!("Executing core command for {}", app.name); true }) } } fn main() { // Create the string first so its lifecycle covers the App instance let name = String::from("Davide"); let app = App { name: &name }; app.run(); }
Why This Works
- Lifecycle Fix: In Option 1,
Appowns the string, so no references or lifecycle annotations are needed. In Option 2, we ensure the original string lives longer thanAppby declaring it first inmain. - Type Mismatch Fix: Each validator function now explicitly takes and returns a
Box<dyn Fn(App) -> bool>(orBox<dyn Fn(App<'a>) -> bool>for the reference version), so the chainvalidator_1(validator_2(box_command()))correctly returns a closure that can accept yourAppinstance.
内容的提问来源于stack exchange,提问作者b1zzu

