我正在尝试使用 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>
.我不确定你想在这里做什么,因为即使是基础 NetworkDetails
和 NetworkCreateInfo
类型不兼容。您需要弄清楚您想要什么类型以及如何在两个分支中获得相同的类型。
编辑更新的问题:好的,你想要一个 String
从两个分支。您有两种不同的类型都实现了 Future<Item = String>
trait,并且您需要两个分支都属于同一类型。这正是 future::Either
的目的。 .只需将一个分支包裹在 Either::A
中和 Either::B
中的另一个分支.
之后,您还会在第一个分支中发现一个微不足道的借用问题:您需要复制带有 net.id.clone()
的字符串.
关于rust - 匹配 future 类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54085424/