2016-04-25 10 views
3

ich in einer Pipeline, wie so einen Wert zu konvertieren im Grunde bin versucht:Verwendung in() innerhalb einer Monade Pipeline

#[derive(PartialEq)] 
enum MyType { A, B } 

impl Into<MyType> for i32 { 
    fn into(self) -> MyType { 
     match self { 
      0 => MyType::A, 
      _ => MyType::B 
     } 
    } 
} 

fn main() { 
    let a: Result<i32,()> = Ok(0); 
    a.map(|int| int.into()) 
     .and_then(|enm| if enm == MyType::A { println!("A"); }); 
} 

Das Problem, das ich in laufen lasse, ist, dass map() wissen nicht, was es gibt sollte ausgegeben werden.

Andere Dinge, die ich habe versucht, was nicht funktioniert hat:

a.map(|int| if int.into() as MyType == MyType::A { println!("A"); }); 

a.map(|int| int.into::<MyType>()) 
     .and_then(|enm| if enm == MyType::A { println!("A"); }); 

Dies funktioniert, fühlt sich aber unnötig komplex:

a.map(|int| { 
    let enm: MyType = int.into(); 
    if enm == MyType::A { println!("A"); } 
}); 

Gibt es einen besseren Weg, dies zu tun?

+0

erklärt Ihr ursprünglicher Code funktioniert nicht, weil 'and_then' erwartet ein 'Ergebnis'. –

Antwort

6

Sie nicht Into Umsetzung werden sollte, sollten Sie sein Implementierung From, die Ihnen automatisch eine Into impl. Dann können Sie rufen a.map(MyType::from) und alles funktioniert:

impl From<i32> for MyType { 
    fn from(i: i32) -> MyType { 
     match i { 
      0 => MyType::A, 
      _ => MyType::B 
     } 
    } 
} 

fn main() { 
    let a: Result<i32,()> = Ok(0); 
    a.map(MyType::from) 
     .and_then(|enm| if enm == MyType::A { Err(()) } else { Ok(enm) }); 
} 

alternativ können Sie a.map(Into::<MyType>::into) nennen, aber das ist ziemlich ausführlich. Es gibt einen Grund für die From/Into Duality, es ist in der std::convert module docs

3

Das Problem, das ich renne, ist, dass map() nicht weiß, welchen Typ es ausgeben sollte.

Das ist nicht das Problem.

Der Fehler ist:

<anon>:16:25: 16:63 error: mismatched types: 
expected `core::result::Result<_,()>`, 
    found `()` 
(expected enum `core::result::Result`, 
    found()) [E0308] 
<anon>:16   .and_then(|enm| if enm == MyType::A { println!("A"); }); 

Das ist, weil Result::and_then ‚s Typ

fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E> 

ist also erwartet, dass sie die Funktion ein Result<U, E> zurückzukehren. Es soll verwendet werden, um Funktionen zu verketten, die eine Result zurückgeben und den ersten aufgetretenen Fehler zurückgeben, wenn dieser auftrifft.

Wenn Sie nur einen Code ausführen möchten, wenn Sie einen Ok(_) haben, sollten Sie if let oder match verwenden:

fn main() { 
    let a: Result<i32,()> = Ok(0); 
    if let Ok(MyType::A) = a.map(|int| int.into()) { 
     println!("A"); 
    } 
} 

druckt

A 
Verwandte Themen