请求,下面这段代码中, impl<'r, A> FromText<'r> for (A,)
能编译通过, impl<'r, A, B> FromText<'r> for (A, B)
却不能编译通过。
应该如何理解这段代码的错误?
Ext Link: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=bfc9d867e1a7c13b3b4812ee7475eab7
1
共 11 条评论, 1 页
评论区
写评论这样更能表达意图 👍
--
👇
苦瓜小仔: 你可以使用 GAT:playground
多谢,又学到一点新知识。
--
👇
苦瓜小仔: 你可以使用 GAT:playground
你可以使用 GAT:playground
@jackalchenxu 谢谢你的回复,不过我这里需要为一些引用实现 FromText, 比如:
而如果使用你建议的方法的话,我就很那做到上面这个实现。
--
👇
jackalchenxu: 不使用您代码中的
'r
生命周期声明,而使用特别的'async_trait
这里是可以编译过的修改版本
是的,我也发现与跨 .await 有关,比如这个代码
--
👇
苦瓜小仔: 还可以把 'r 放到函数上
至于 Send 问题,那是因为跨 .await,注意我的链接并没有
B::Output: Send
。而这里的生命周期问题,也与跨 .await 有关(貌似目前这方面有点混乱),见 https://github.com/rust-lang/rust/issues/102211。
我已经将这里的例子提交到了那个 issue。
还可以把 'r 放到函数上
至于 Send 问题,那是因为跨 .await,注意我的链接并没有
B::Output: Send
。而这里的生命周期问题,也与跨 .await 有关(貌似目前这方面有点混乱),见 https://github.com/rust-lang/rust/issues/102211。
不使用您代码中的
'r
生命周期声明,而使用特别的'async_trait
这里是可以编译过的修改版本
@Jasonwu123 我有一个办法证明不是
Send
的问题 ,见这个 playground上面的playground什么都不变,只是不调用
B::parse(text).await
(见37行),并用todo!()
帮忙通过编译, 也不用增加Self::Output
的约束,结果也可以编译通过。因此应该不是Send
的问题。--
👇
wukong: 这样会有递归的报错,见 playground 的错误
同时我也有疑问,A 和 B 都是 Send 后, (A, B) 不就是 Send 了吗?
另外,我不使用 async_trait 这个库,而使用 AFIT 和 impl_trait_projections 这两个 nightly 特性时就不会有问题,见 playground
--
👇
Jasonwu123: 这个问题是由于Rust编译器在编译时,对于
async fn
的返回类型需要满足Send
约束。这是因为异步操作可能在不同的线程之间传递。在第一个实现中,代码可以正常编译,因为单元素元组(A::Output
,)默认满足Send
。但在第二个实现中,需要明确指出A::Output
和B::Output
满足Send
。你已经在
where
子句中添加了A::Output: Send
和B::Output: Send
。但是,async_trait
库要求Output
类型也必须满足Send
。在实现(A, B)
的代码中,应该将type Output
改为:同时,需要在
where
子句中添加Output
类型满足Send
的约束:完整的实现应如下:
这样修改后,代码应该可以编译通过。
这样会有递归的报错,见 playground 的错误
同时我也有疑问,A 和 B 都是 Send 后, (A, B) 不就是 Send 了吗?
另外,我不使用 async_trait 这个库,而使用 AFIT 和 impl_trait_projections 这两个 nightly 特性时就不会有问题,见 playground
--
👇
Jasonwu123: 这个问题是由于Rust编译器在编译时,对于
async fn
的返回类型需要满足Send
约束。这是因为异步操作可能在不同的线程之间传递。在第一个实现中,代码可以正常编译,因为单元素元组(A::Output
,)默认满足Send
。但在第二个实现中,需要明确指出A::Output
和B::Output
满足Send
。你已经在
where
子句中添加了A::Output: Send
和B::Output: Send
。但是,async_trait
库要求Output
类型也必须满足Send
。在实现(A, B)
的代码中,应该将type Output
改为:同时,需要在
where
子句中添加Output
类型满足Send
的约束:完整的实现应如下:
这样修改后,代码应该可以编译通过。
这个问题是由于Rust编译器在编译时,对于
async fn
的返回类型需要满足Send
约束。这是因为异步操作可能在不同的线程之间传递。在第一个实现中,代码可以正常编译,因为单元素元组(A::Output
,)默认满足Send
。但在第二个实现中,需要明确指出A::Output
和B::Output
满足Send
。你已经在
where
子句中添加了A::Output: Send
和B::Output: Send
。但是,async_trait
库要求Output
类型也必须满足Send
。在实现(A, B)
的代码中,应该将type Output
改为:同时,需要在
where
子句中添加Output
类型满足Send
的约束:完整的实现应如下:
这样修改后,代码应该可以编译通过。