Rust 匹配未来类型

Rust 匹配未来类型,rust,future,rust-tokio,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

我正在尝试使用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);
}
我的匹配表达式中似乎存在类型不匹配。我试图确保每个arm都包含shiplift网络结构的未来,但看起来我还没有完全理解它

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
错误[E0308]:匹配臂的类型不兼容
-->src/up/mod.rs:168:13
|
168 |/匹配网络{
169 | |//在网络上传递
170 | | Some(net)=>future::ok(net.id),
171 | |//创建新网络
...   |
178 | |                 }
179 | |             }
||uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu`
|
=注:预期类型“futures::FutureResult”`
找到类型“futures::Map”`
注意:将arm与不兼容的类型匹配
-->src/up/mod.rs:172:25
|
172 |无=>{
|  _________________________^
173 | |让docker=docker::new();
174 | |码头工人
175 | |网络()
176 | |.create(&NetworkCreateOptions::builder(name).driver(“桥”).build())
177 | | | map(| new|u net | new|u net.id)
178 | |                 }
| |_________________^
错误:由于上一个错误而中止

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

移除
,您将看到类型仍然不匹配。
Some
分支具有类型
futuresult
,而
None
分支现在具有类型
impl Future
。我不确定您在这里想做什么,因为即使是基本的
NetworkDetails
NetworkCreateInfo
类型也不兼容。您需要弄清楚您想要什么类型,以及如何在两个分支中获得相同的类型

编辑以更新问题:好的,您希望从两个分支中获得一个
字符串。您有两种不同的类型,它们都实现了
Future
trait,并且您需要两个分支都是相同的类型。这正是我们的目的。只需将一个分支包装在
other::A
中,将另一个分支包装在
other::B
中即可


在这之后,您还会在第一个分支中发现一个微不足道的借用问题:您需要使用
net.id.clone()

复制字符串。我已经基于此编辑了问题。考虑到
NetworkDetails
NetworkCreateInfo
不是类型,我认为最好的选择是将网络id作为
&str
返回。