mit Ich versuche, den folgenden vereinfachten Code zu kompilieren:Wert „leben nicht lange genug“, aber nur dann, wenn ein Funktionszeiger
type FunctionType<'input> = fn(input_string: &'input str) -> Result<(), &'input str>;
fn okay<'input>(_input_string: &'input str) -> Result<(), &'input str> {
Ok(())
}
fn do_stuff_with_function(function: FunctionType) {
let string = String::new();
match function(string.as_str()) {
Ok(_) => {},
Err(_) => {},
}
}
fn main() {
do_stuff_with_function(okay);
}
Der Spielplatz klagt:
error[E0597]: `string` does not live long enough
--> src/main.rs:13:20
|
13 | match function(string.as_str()) {
| ^^^^^^ does not live long enough
...
18 | }
| - borrowed value only lives until here
|
note: borrowed value must be valid for the anonymous lifetime #1 defined on the function body at 11:1...
--> src/main.rs:11:1
|
11 |/fn do_stuff_with_function(function: FunctionType) {
12 | | let string = String::new();
13 | | match function(string.as_str()) {
14 | | Ok(_) => {},
... |
17 | |
18 | | }
| |_^
Ich verstehe, warum der Fehler unter anderen Umständen auslösen würde: string
lebt nur so lange wie die Ausführung von do_stuff_with_function
, aber do_stuff_with_function
gibt den Wert von function
Aufruf zurück, der eine Referenz für die gleiche Lebenszeit auf seinem Eingabewert enthält h., string
.
Allerdings bin ich auf drei Punkte verwirrt:
- ich das Ergebnis des Funktionsaufrufs
match
, dann()
Return für beide Zweige. Warum ist die Lebensdauer des Werts, der vonfunction
zurückgegeben wird, von Bedeutung, wenn er bedingungslos verworfen wird? - Wenn ich den Aufruf des Parameters
function
mit einem direkten Verweis aufokay
(die eine identische Signatur hat) ersetzen, kompiliert es ohne Beanstandung. - Die Fehlermeldung schlägt vor (obwohl nicht direkt angeben?), Dass die erforderliche Lebensdauer bereits die tatsächliche Lebensdauer ist.
Dies funktioniert für meinen Fall! Ich bin mir immer noch nicht sicher, warum Punkt (1) in meiner ursprünglichen Frage nicht ausreicht, um den Compiler zufrieden zu stellen, und traurig ist, dass Sie den Alias inline (der echte, den ich habe, ist ziemlich riesig), aber froh, dass dies möglich ist mit freaky Art Magie. – stuffy
@stuffy, Sie müssen den Alias nicht inline einfügen. 'für <'_>' kann hinzugefügt werden. [Playground] (https://play.rust-lang.org/?gist=bbd442124db421e7201baa5b29ea7829&version=stable) – red75prime
Sie können auch '<'input>' vom Typ Alias entfernen. 'type FunctionType = fn (input_string: & str) -> Ergebnis <(), &str>;' Lifetime elision wird das Richtige tun. – red75prime