rust - 匹配 future 类型

标签 rust future rust-tokio

我正在尝试使用 futures 来异步查找一个值。如果该值存在,我想返回它,如果不存在,我想创建它。

// A network will be created unless one already exists with this name
pub fn build_network(name: &'static str) {
    let docker = Docker::new();

    // Get a list of networks
    let fut = docker
        .networks()
        .list(&Default::default())
        .and_then(move |networks| {
            // Check if a network with the given name exists  
            let network = networks.iter().find(|n| n.name == name);

            match network {
                // Pass on network
                Some(net) => future::ok(net.id),
                // Create a new network
                None => {
                    let docker = Docker::new();
                    docker
                        .networks()
                        .create(&NetworkCreateOptions::builder(name).driver("bridge").build())
                        .map(|new_net| new_net.id)

                }
            }
        })
        .map(move |net| {
            println!("{:#?}", net);
        })
        .map_err(|e| eprintln!("Error: {}", e));

    tokio::run(fut);
}

看起来我的匹配表达式中存在类型不匹配。我正在尝试确保每个臂都包含一个升船机网络结构的 future ,但看起来我不太明白。

error[E0308]: match arms have incompatible types
   --> src/up/mod.rs:168:13
    |
168 | /             match network {
169 | |                 // Pass on network
170 | |                 Some(net) => future::ok(net.id),
171 | |                 // Create a new network
...   |
178 | |                 }
179 | |             }
    | |_____________^ expected struct `futures::FutureResult`, found struct `futures::Map`
    |
    = note: expected type `futures::FutureResult<std::string::String, _>`
               found type `futures::Map<impl futures::Future, [closure@src/up/mod.rs:177:30: 177:50]>`
note: match arm with an incompatible type
   --> src/up/mod.rs:172:25
    |
172 |                   None => {
    |  _________________________^
173 | |                     let docker = Docker::new();
174 | |                     docker
175 | |                         .networks()
176 | |                         .create(&NetworkCreateOptions::builder(name).driver("bridge").build())
177 | |                         .map(|new_net| new_net.id)
178 | |                 }
    | |_________________^

error: aborting due to previous error

最佳答案

你最明显的错误是 ;None 的末尾分支。分号总是丢弃前一个表达式的值,以分号结尾的 block 的类型为 () (假设终点可达)。

删除 ; 后,你会看到类型仍然不匹配。 Some分支有类型 FutureResult<&NetworkDetails> , 而 None分支现在有类型 impl Future<Item = NetworkCreateInfo> .我不确定你想在这里做什么,因为即使是基础 NetworkDetailsNetworkCreateInfo类型不兼容。您需要弄清楚您想要什么类型以及如何在两个分支中获得相同的类型。

编辑更新的问题:好的,你想要一个 String从两个分支。您有两种不同的类型都实现了 Future<Item = String> trait,并且您需要两个分支都属于同一类型。这正是 future::Either 的目的。 .只需将一个分支包裹在 Either::A 中和 Either::B 中的另一个分支.

之后,您还会在第一个分支中发现一个微不足道的借用问题:您需要复制带有 net.id.clone() 的字符串.

关于rust - 匹配 future 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54085424/

相关文章:

rust - 使用Arrow/Datafusion/Polars(如python panda的groupby)按列值分区?

string - Rust 中的 String 基本上是一个向量吗?

Flutter、Dart 和 Future。这是 Dart Futures 的已知功能并且为空吗?

scala - 在 Controller 中使用 Future 的最佳实践 (Play+Scala)

rust - 等待 mpsc channel 有消息但未收到任何消息

asynchronous - 串的Rust future

asynchronous - 从 Tokio 应用程序使用 Actix:混合 actix_web::main 和 tokio::main?

firefox - 您可以使用 Rust 编写 Firefox 附加组件/扩展吗?

rust - 如何检查大于 2 ^ 54 的 u64 数是否可以被 f64 整除且精度损失最小?

rust - 您如何通过采用&mut self的方法调用存储在结构中的Future上的future::select?