< 返回版块

zjhken 发表于 2022-01-02 22:07

Tags:where,async

正确的版本是这样的

pub async fn f1<F, Fut>(f: F) -> u32
where
    F: Fn(u32) -> Fut,
    Fut: Future<Output = u32>,
{
    f(9u32).await
}

但是Rust文档说了, where就是一个方便的写法, 于是试着直接替换掉对应的类型标记

pub async fn f2(f: Fn(u32) -> Future<Output = u32>) -> u32 {
    f(9u32).await
}

这下编译不过了, 报了这个错误 error: trait objects must include the dyn keyword

请问这个where在这里实际起到的功能是什么? 是不是用什么魔法? 真正去掉where的写法应该是怎样的?

评论区

写评论
苦瓜小仔 2022-01-02 22:44

你似乎没有正确理解 trait bound

https://doc.rust-lang.org/nightly/reference/trait-bounds.html

作者 zjhken 2022-01-02 22:41

似乎明白了, 也就是说, 除了 Trait1 + Trait2, Future<Output=u32>也是一种trait bound, 只要是trait bound, 原本的写法就必须写泛型参数, 所以必须写Fut

作者 zjhken 2022-01-02 22:32

感谢苦瓜小仔和Grobycn的解答.

我能理解Trait bound, 就是当指定一个类型要同时符合两个Trait, 类似Display + Clone 但是在这里, 两位的解答中似乎是一定要额外指定一个Fut, 而这个Fut并不是Trait1 + Trait2这种要求两个Trait的情况, 那为什么无法不使用Fut呢?

苦瓜小仔 2022-01-02 22:28

BTW

报错提示的 dyn 只是一种处理办法(Rust 的编译器通常会给你解决的方法),它与 where 语句无关。

where 语句比 impl trait 或者 trait bound 语法具有更多表现力,详细见 RFC: 0135-where

从另一个角度看,impl trait 或者 trait bound 是 where 语句的语法糖。

苦瓜小仔 2022-01-02 22:20
pub async fn f1<Fut: Future<Output = u32>>(f: impl Fn(u32) -> Fut) -> u32 { f(9u32).await }
pub async fn f2<F: Fn(u32) -> Fut, Fut: Future<Output = u32>>(f: F) -> u32 { f(9u32).await }

https://doc.rust-lang.org/book/ch10-02-traits.html#clearer-trait-bounds-with-where-clauses

Grobycn 2022-01-02 22:20
pub async fn f1<F: Fn(u32) -> Fut, Fut: Future<Output = u32>>(f: F) -> u32 {
    f(9u32).await
}
1 共 6 条评论, 1 页