代码如下:
use smol::io::{AsyncWrite, Cursor};
use std::fmt::Debug;
use std::future::Future;
#[derive(Eq, PartialEq, Debug)]
struct Data {}
impl Data {
async fn serialize<W: AsyncWrite>(&self, _: &mut W) {}
fn deserialize(_: &[u8]) -> Self {
todo!()
}
}
fn test_serialization<'a, V: 'a, S, O, D>(v: V, serialize: S, deserialize: D)
where
for<'b> S: FnOnce(&'a V, &'b mut Cursor<Vec<u8>>) -> O,
O: Future,
D: FnOnce(&[u8]) -> V,
V: Eq + Debug,
{
let mut buf = vec![0;4096];
serialize(&v, &mut Cursor::new(buf));
let parsed = deserialize(&buf);
assert_eq!(v, parsed);
}
fn main() {
let data = Data {};
test_serialization(data, Data::serialize, Data::deserialize);
}
这段代码过不了编译, 错误是
error: implementation of `FnOnce` is not general enough
--> xxx.rs:30:5
|
30 | test_serialization(data, Data::serialize, Data::deserialize);
| ^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
::: /home/xxx/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:219:1
|
219 | / pub trait FnOnce<Args> {
220 | | /// The returned type after the call operator is used.
221 | | #[lang = "fn_once_output"]
222 | | #[stable(feature = "fn_once_output", since = "1.12.0")]
... |
227 | | extern "rust-call" fn call_once(self, args: Args) -> Self::Output;
228 | | }
| |_- trait `FnOnce` defined here
|
= note: `FnOnce<(&Data, &'0 mut smol::io::Cursor<Vec<u8>>)>` would have to be implemented for the type `for<'_, '_> fn(&Data, &mut smol::io::Cursor<Vec<u8>>) -> impl Future {Data::serialize::<smol::io::Cursor<Vec<u8>>>}`, for some specific lifetime `'0`...
= note: ...but `FnOnce<(&Data, &'b mut smol::io::Cursor<Vec<u8>>)>` is actually implemented for the type `for<'_, '_> fn(&Data, &mut smol::io::Cursor<Vec<u8>>) -> impl Future {Data::serialize::<smol::io::Cursor<Vec<u8>>>}`
如果我把for<'b> S: FnOnce(&'a V, &'b mut Cursor<Vec<u8>>) -> O,
改成S: FnOnce(&'a V, &'a mut Cursor<Vec<u8>>) -> O
, 那么调用那里不会报错了,但是函数内部会报cursor
生命周期不够长的错。这段代码到底该怎么改?难道只能用宏?我觉得这个需求实在不是特别刁钻。
1
共 4 条评论, 1 页
评论区
写评论然后问题就变成了下面这个函数不能用,最后我还是用宏解决了。
这样是可以的:
改了还是不行
--
👇
tcz717: 你的闭包函数参数是mut借用 得改成FnMut
你的闭包函数参数是mut借用 得改成FnMut