2016-10-06 1 views
0

In Rust, wenn ich eine Schließung als solche definiert kehre zurück:Wie kann eine Rust-Schließung String-Argumente und Rückgabewerte annehmen?

fn closure_thing() (Fn(String) -> String) { 
    |thing| { 
     thing[1..4] 
    } 
} 

Ich erhalte einen Fehler zu:

= note: `std::ops::Fn(std::string::String) -> std::string::String + 'static` does not have a constant size known at compile-time 
= note: the return type of a function must have a statically known size` 

Ich habe versucht, Fn (& String) -> & String als auch. Gibt es einen einfachen Weg für eine Schließung, eine Zeichenkette als Argument zu nehmen und eine Zeichenkette zurückzugeben?

Antwort

3

Fn ist ein Merkmal. Du kannst ein Merkmal nicht zurückgeben. Sie können jedoch einen Funktionszeiger zurück:

fn closure_thing() -> (fn(String) -> String) { 
    fn foo(thing: String) -> String { 
     … 
    } 

    foo 
} 

Sie auch eine Box zurückkehren können:

fn closure_thing() -> Box<Fn(String) -> String> { 
    Box::new(|thing| { 
     … 
    }) 
} 

Aber das hat man einen Laufzeitkosten, so sollte als letztes Mittel in Betracht gezogen werden.

Wie @Veedrac erwähnt, können Sie auch impl Trait verwenden:

#![feature(conservative_impl_trait)] 

fn closure_thing() -> impl Fn(String) -> String { 
    |thing| { 
     … 
    } 
} 

Aber wie Rust 1.12 dies ist noch nicht stabil und erfordert einen nächtlichen Compiler. Sie können jedes Merkmal ohne die Laufzeitkosten der vorherigen Lösung zurückgeben.

+1

Ihre ersten beiden haben auch (potenzielle) Laufzeitkosten, da sie dynamischen Versand beinhalten. AFAIK ist die einzige Lösung, "impl Trait" zu verwenden. – Veedrac

+0

Sie sollten wahrscheinlich erwähnen, dass Ihr erstes Beispiel nicht direkt funktioniert, da die Schließung nicht lange genug dauert (es sei denn, ich vermisse etwas). –

+1

@ErikVesteraas TIL borrowck läuft nach der "Hauptfunktion nicht gefunden", die ein fataler Fehler ist – mcarton

2

der Rückgabetyp einer Funktion muss

Eine Möglichkeit, eine statisch bekannte Größe haben zu erreichen, dass der Verschluss boxen ...

fn closure_thing() -> Box<Fn(String) -> String> { 
    Box::new(|thing| { 
     (&thing[1..4]).to_string() 
    }) 
} 

Bitte beachte, dass ich das auch umgewandelt Ergebnis zu einem String .. seit dem Schneiden wird eine str zurückgeben.

Wie von Mcarton angemerkt, verursacht das Boxen einen Laufzeitaufwand für die Heap-Zuweisung.

Verwandte Themen