下面这么写是能跑的, 代码非常简单.
use core::future::Future;
async fn haha(ctx: u8) -> u8 {
return 2u8;
}
fn set_func<T>(path: &'static str, f: fn(u8) -> T) -> u8
where
T: Future<Output = u8> + Send + 'static,
{
return 8u8;
}
fn main() {
set_func("haha", haha);
}
但是当改了一下haha函数的入参 u8 -> &mut u8, 事情就不一样了
use core::future::Future;
async fn haha(ctx: &mut u8) -> u8 {
return 2u8;
}
fn set_func<T>(path: &'static str, f: fn(&mut u8) -> T) -> u8
where
T: Future<Output = u8> + Send + 'static,
{
return 8u8;
}
fn main() {
set_func("haha", haha);
}
报错, 说是类型不匹配, 哪位大侠知道这是啥原因? 是从fn pointer变吃fn item了吗? 有没有办法保留这个&mut u8, 让类型检查通过?
|
13 | set_func("haha", haha);
| -------- ^^^^ one type is more general than the other
| |
| arguments to this function are incorrect
|
= note: expected fn pointer `for<'a> fn(&'a mut u8) -> _`
found fn item `for<'a> fn(&'a mut u8) -> impl Future<Output = u8> {haha}`
1
共 8 条评论, 1 页
评论区
写评论补充一下 fn item 和 fn pointer 的区别,来自标准库文档
非常感谢苦瓜大大, 确实解决了. (虽然又遇到了另一个问题, 不过是另外的问题了)
--
👇
苦瓜小仔:
这进入了 HRTB 的主场。
无论你在现有的 set_func 上怎么标注生命周期,都没有用。因为这种情况下,你需要描述
for<'a> fn(&'a mut u8) -> T where T: 'a
约束(注意,这不是 Rust 目前支持的 trait bound 语法)。目前有两种主流 workaround。 playground一个案例
感谢Grobycn, 确完两者都可以通过这个例子, 但就如同苦瓜大大所说, 我晚上试了这两个方法, 都无法通过实际的代码, 因为里面要用到haha这个函数时, 生命周期就出来报错了, 搞了好久都没搞过去.
--
👇
Grobycn: 这是生命周期问题,
haha
的返回值类型impl Future<Output = u8>
,但是set_func
要求f: impl Future<Output = u8> + Send + 'static
。 估计是传入的参数&mut u8
导致编译器无法推断出'static
, 可以手动 desugar 成 也可以修改 set_func 的约束条件是的。
其他两位的写法可以通过这个例子,但其实很局限。(如果这已经能满足你的要求,那么很好:)
考虑在 set_func 函数内部,把函数内的变量传入 haha,那么你会遇到明确的生命周期的问题 playground。
这进入了 HRTB 的主场。
无论你在现有的 set_func 上怎么标注生命周期,都没有用。因为这种情况下,你需要描述
for<'a> fn(&'a mut u8) -> T where T: 'a
约束(注意,这不是 Rust 目前支持的 trait bound 语法)。目前有两种主流 workaround。 playground一个案例
好像加个'a就过了
苦瓜大大, 能否这么理解, 其实这个haha函数既是fn pointer也是fn item, 而编译器complain的其实不是pointer和item的区别, 而是类型细节中的返回值的区别, 一个为
_
,一个为impl...
?--
👇
苦瓜小仔: 关于异步函数中的生命周期,请确保完全理解
https://rust-lang.github.io/async-book/03_async_await/01_chapter.html#async-lifetimes
即,异步函数+生命周期是如何解语法糖。
查找概念,首先翻 the Reference
你所定义的
haha
是一个 function item,也是一个function pointer type。因为两者具有如下关系:
关于异步函数中的生命周期,请确保完全理解
https://rust-lang.github.io/async-book/03_async_await/01_chapter.html#async-lifetimes
即,异步函数+生命周期是如何解语法糖。
查找概念,首先翻 the Reference
你所定义的
haha
是一个 function item,也是一个function pointer type。因为两者具有如下关系:
这是生命周期问题,
haha
的返回值类型impl Future<Output = u8>
,但是set_func
要求f: impl Future<Output = u8> + Send + 'static
。 估计是传入的参数&mut u8
导致编译器无法推断出'static
, 可以手动 desugar 成也可以修改 set_func 的约束条件