2016-08-12 3 views
3

Ich möchte eine Context-Struktur haben, die in allen Handlern verfügbar ist, aber ich bin nicht in der Lage, durch den Compiler zu bekommen.Wie kann ich Variablen zwischen Handlern übergeben

Ein Beispiel möchte ich so etwas wie dieses

extern crate iron; 
extern crate router; 

use iron::prelude::*; 
use router::Router; 
use std::collections::HashMap; 

struct Context { 
    cache: HashMap<String, String>, 
} 

fn main() { 
    let mut context = Context { cache: HashMap::new(), }; 
    let mut router = Router::new(); 

    router.get("/", |request| index(request, context)); 

    Iron::new(router).http("localhost:80").unwrap(); 
} 


fn index(_: &mut Request, context: Context) -> IronResult<Response> { 
    Ok(Response::with((iron::status::Ok, "index"))) 
} 

Dies wird mit einer langen Fehlermeldung nicht kompilieren

error: type mismatch resolving `for<'r, 'r, 'r> <[[email protected]\main.rs:... context:_] as std::ops::FnOnce<(&'r mut iron::Request<'r, 'r>,)>>::Output == std::result::Result<iron::Response, iron::IronError>`: 
expected bound lifetime parameter , 
    found concrete lifetime [E0271] 
src\main.rs:...  router.get("/", |request| index(request, context)); 

Antwort

4

Die Fehlermeldung hier fast unverständlich ist (es gibt eine issue für es!).

Das Problem ist, dass der Typ der Schließung nicht abgeleitet wird. Wir können die Compiler helfen, die Art von request Kommentierung:

extern crate iron; 
extern crate router; 

use iron::prelude::*; 
use router::Router; 
use std::collections::HashMap; 
use std::sync::{Arc, Mutex}; 

#[derive(Clone, Default)] 
struct Context { 
    cache: Arc<Mutex<HashMap<String, String>>>, 
} 

fn main() { 
    let context = Context::default(); 
    let mut router = Router::new(); 

    let c = context.clone(); 
    router.get("/", move |request: &mut Request| index(request, &c), "index"); 

    Iron::new(router).http("localhost:80").unwrap(); 
} 

fn index(_: &mut Request, context: &Context) -> IronResult<Response> { 
    Ok(Response::with((iron::status::Ok, "index"))) 
} 

Bitte beachte, dass ich die Art von context-&Context geändert (sonst wäre die Schließung nur implementsFnOnce) und verwenden move (die Schließung 'static Lebensdauer haben muss zu implementieren Handler).

Um es zu ermöglichen cache in index zu ändern, die Sie change den Typ Arc<Mutex<HashMap<String, String>>> oder ähnliches haben.

+0

Vielen Dank dafür. Jetzt habe ich das nicht in meinem ursprünglichen Problem erwähnt, aber ich habe mehr als eine dieser router.get-Linien (was ist der Punkt der Verwendung eines Routers) und eine zweite Zeile hinzufügen (router.get ("/ hi" , move | ... | hi (...));) führt zu neuen Compilerfehlern. Fehler: Erfassung des verschobenen Wertes: 'context' – Nozdrum

+0

@Nozdrum Siehe das Update. – malbarbo

+0

Nochmals vielen Dank dafür. Es gibt eine Menge, die ich hier nicht verstehe (warum muss ich alles klonen, wenn der Inhalt der Struktur gleich ist, warum muss ich meinen Verschluss "bewegen" und was bedeutet das überhaupt, warum sind diese abgeleitet? an meiner Struktur). Ich habe das Buch über die Programmierung des Rosts gelesen und stelle jetzt fest, dass ich nicht wirklich verstehe, was sie dort geschrieben haben. – Nozdrum

Verwandte Themen