在try 有条件地创建future 时,为了以后与select_biased!一起使用:

            let mut heartbeat_timer = if let ServerState::Leader(_, _, _) = server_state {
                // if we're the Leader, we want to send out AppendEntries RPC at a
                // minimum interval as required to maintain our leadership
                task::sleep(HEARTBEAT_DURATION)
            } else {
                // if we're not the leader, no need to send those
                pending::<()>()
            };

// ...

            select_biased! {
                h = heartbeat_timer => self.heartbeat().await,
                // ... some others declared in priority order
                default => task::yield_now().await,
            }

我很难理解为什么会出现编译错误:

error[E0308]: `if` and `else` have incompatible types
   --> src/raft.rs:185:17
    |
182 |               let heartbeat_timer = if let ServerState::Leader(_, _, _) = server_state {
    |  ___________________________________-
183 | |                 task::sleep(HEARTBEAT_DURATION)
    | |                 ------------------------------- expected because of this
184 | |             } else {
185 | |                 pending::<()>()
    | |                 ^^^^^^^^^^^^^^^ expected future, found `Pending<()>`
186 | |             };
    | |_____________- `if` and `else` have incompatible types
    |
    = note: expected opaque type `impl futures::Future<Output = ()>`
                    found struct `futures::future::Pending<()>`

单击(在我的IDE中)pending会显示它的类型是Pending<T>,我还可以进一步看到Pending<T>实现了Future<Output=T>:

impl<T> Future for Pending<T> {
    type Output = T;

    fn poll(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<T> {
        Poll::Pending
    }
}

出于某种原因,我还不能理解,编译器没有遵循相同的面包屑.编译器知道我遗漏了什么秘密?我的代码有没有一些直接的转换可以满足编译器的要求?我应该怎么想才能提供编译器所需要的东西呢?

rustup --version包括输出:

info: The currently active `rustc` version is `rustc 1.69.0 (84c898d65 2023-04-16)`

推荐答案

不幸的是,impl返回类型不能以这种方式工作.它们不是动态分派;impl返回类型必须仍然是single具体类型;只是您不必在代码中指定类型.如果您有两个(或更多)分支臂返回不同类型,则impl返回将拒绝它.如果您想要这样做,您必须使用完全动态调度.这意味着dyn特征对象和Box或其他间接机制.

在你的情况下,我可能建议用Box<dyn Future<Output=()>>代替impl Future<Output=()>.在每个分支上,您必须围绕所需的返回值执行显式Box::new,以添加间接层.

Rust相关问答推荐

将此字符串转换为由空格字符分隔的空格

在HashMap中插入Vacant条目的可变借位问题

如何在Bevy/Rapier3D中获得碰撞机的计算质量?

有没有办法在Rust中配置常量变量的值?

在决定使用std::Sync::Mutex还是使用Tokio::Sync::Mutex时,操作系统线程调度是考虑因素吗?

用于判断整数块是否连续的SIMD算法.

为什么`str`类型可以是任意大小(未知大小),而`string`类型的大小应该是已知的?

为什么rustc会自动降级其版本?

将泛型中的 Box 转换为 rust 中的 Box

如果不满足条件,如何在 Rust 中引发错误

为什么 File::read_to_end 缓冲区容量越大越慢?

将原始可变指针传递给 C FFI 后出现意外值

如何在 Rust 中创建最后一个元素是可变长度数组的 struct ?

如何在 C++ 和 Rust 之间共享 pthread 同步原语?

Rustfmt 是否有明确类型的选项?

需要括号的宏调用中的不必要的括号警告 - 这是编写宏的糟糕方法吗?

如何构建包含本地依赖项的 docker 镜像?

如何在 Rust 的内置函数上实现特征?

返回引用的返回函数

您不能borrow 对只读值的可变引用