在 monad 管道中使用 into()
Using into() inside a monad 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"); });
}
我 运行 遇到的问题是 map()
不知道应该输出哪种类型。
我尝试过但没有用的其他方法:
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"); });
这确实有效,但感觉不必要的复杂:
a.map(|int| {
let enm: MyType = int.into();
if enm == MyType::A { println!("A"); }
});
有更好的方法吗?
The problem I'm running into is that map()
doesn't know which type it should be outputting.
不是这个问题。
错误是:
<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"); });
那是因为Result::and_then
的类型是
fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E>
所以它期望函数return一个Result<U, E>
。它旨在用于将 return 和 Result
的函数链接到 return 第一个遇到的错误(如果遇到任何错误)。
如果你只是想执行一些代码,如果你有 Ok(_)
,你应该使用 if let
或 match
:
fn main() {
let a: Result<i32, ()> = Ok(0);
if let Ok(MyType::A) = a.map(|int| int.into()) {
println!("A");
}
}
打印
A
你不应该实现 Into
,你应该实现 From
,它会自动给你一个 Into
实现。然后你可以调用 a.map(MyType::from)
一切正常:
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) } );
}
或者您可以调用 a.map(Into::<MyType>::into)
,但这相当冗长。 From
/Into
双重性是有原因的,在 std::convert
module docs
中有解释
我基本上是在尝试像这样在管道内转换一个值:
#[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"); });
}
我 运行 遇到的问题是 map()
不知道应该输出哪种类型。
我尝试过但没有用的其他方法:
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"); });
这确实有效,但感觉不必要的复杂:
a.map(|int| {
let enm: MyType = int.into();
if enm == MyType::A { println!("A"); }
});
有更好的方法吗?
The problem I'm running into is that
map()
doesn't know which type it should be outputting.
不是这个问题。
错误是:
<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"); });
那是因为Result::and_then
的类型是
fn and_then<U, F: FnOnce(T) -> Result<U, E>>(self, op: F) -> Result<U, E>
所以它期望函数return一个Result<U, E>
。它旨在用于将 return 和 Result
的函数链接到 return 第一个遇到的错误(如果遇到任何错误)。
如果你只是想执行一些代码,如果你有 Ok(_)
,你应该使用 if let
或 match
:
fn main() {
let a: Result<i32, ()> = Ok(0);
if let Ok(MyType::A) = a.map(|int| int.into()) {
println!("A");
}
}
打印
A
你不应该实现 Into
,你应该实现 From
,它会自动给你一个 Into
实现。然后你可以调用 a.map(MyType::from)
一切正常:
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) } );
}
或者您可以调用 a.map(Into::<MyType>::into)
,但这相当冗长。 From
/Into
双重性是有原因的,在 std::convert
module docs