模式匹配和返回类型统一

时间:2018-12-07 10:51:18

标签: rust pattern-matching amqp

我正在使用Rust编写一个小程序,连接到RabbitMQ以发送消息(使用lapin-futures),使用以下代码会有些困难:

fn interpret_action(
    channel: &channel::Channel<TcpStream>,
    action: Action,
) -> impl Future<Item = (), Error = std::io::Error> + Send + 'static {
    match action {
        Action::DoNothing => {
            debug!("Doing nothing");
            futures::future::ok(())
        }
        Action::SendMsg(MessageDispatch { message, delay: _ }) => {
            info!("Publishing a message: {:?}", message);
            let mut rng = thread_rng();
            let message_id: String = iter::repeat(())
                .map(|()| rng.sample(Alphanumeric))
                .take(16)
                .collect();
            channel
                .basic_publish(
                    &*message.route.exchange,
                    &*message.route.routing_key,
                    message.body.0.into_bytes(),
                    channel::BasicPublishOptions::default(),
                    channel::BasicProperties::default()
                        .with_message_id(message_id)
                        .with_user_id("guest".to_string()),
                )
                .map(|_| ())
        }
        _ => {
            debug!("Don't know what to do");
            futures::future::ok(())
        }
    }
}

编译器在抱怨:

error[E0308]: match arms have incompatible types                                                                                           
       --> lib/src/server/mod.rs:127:3                                                                                                         
        |                                                                                                                                      
    127 | /   match action {                                                                                                                   
    128 | |     Action::DoNothing => {                                                                                                         
    129 | |       debug!("Doing nothing");                                                                                                     
    130 | |       futures::future::ok(())                                                                                                      
    ...   |                                                                                                                                    
    154 | |     }                                                                                                                              
    155 | |   }                                                                                                                                
        | |___^ expected struct `futures::FutureResult`, found struct `futures::Map`                                                           
        |                                                                                                                                      
        = note: expected type `futures::FutureResult<(), _>`                                                                                   
                   found type `futures::Map<impl std::marker::Send+futures::Future, [closure@lib/src/server/mod.rs:149:14:149:20]>`           
    note: match arm with an incompatible type                                                                                                  
        --> lib/src/server/mod.rs:132:63                                                                                                        
        |                                                                                                                                      
    132 |       Action::SendMsg(MessageDispatch { message, delay: _ }) => {                                                                    
        |  _______________________________________________________________^                                                                    
    133 | |       info!("Publishing a message: {:?}", message);                                                                                
    134 | |       let mut rng = thread_rng();                                              
    135 | |       let message_id: String = iter::repeat(())                                                                                    
    ...   |                                                                                                                                    
    149 | |         .map(|_| ())                                                                                                               
    150 | |     }                                                                                                                              
        | |_____^

据我了解,我需要统一分支之间的类型,但是我希望情况已经如此,因为MapFutureResult都应与impl特性匹配。一种选择是使用有效的Box。但是我真的很想知道我是否可以避免使用Box,如果不可能,为什么不可能呢。我怀疑使用闭包类型会使事情变得不可能,但不确定。

谢谢您的帮助!

0 个答案:

没有答案