如何将外部关联类型强制转换为我的本地结构类型?
How to coerce external associated types to my local struct types?
我有以下结构:
pub struct Liquidator<'a, P> {
// ...
pending_liquidations: HashMap<Address, PendingTransaction<'a, P>>,
// ...
}
其中 PendingTransaction
是从 ethers-rs 导入的结构:
pub struct PendingTransaction<'a, P> {
// ...
provider: &'a Provider<P>,
// ...
}
我正在实例化我的 Liquidator
结构并试图在 pending_transactions
中插入一个元素:
pub async fn do_something(&mut self, borrower: &Address) {
// ...
let pending_tx = contract_call.send().await?;
self.pending_liquidations.entry(*borrower).or_insert(pending_tx);
}
(这里是send
方法的definition)。
但代码无法编译:
error[E0308]: mismatched types
--> liquidator/src/liquidator.rs:115:70
|
24 | impl<'a, P> Liquidator<'a, P>
| - this type parameter
...
115 | self.pending_liquidations.entry(*borrower).or_insert(pending_tx);
| ^^^^^^^^^^ expected type parameter `P`, found associated type
|
= note: expected struct `ethers::prelude::PendingTransaction<'a, P>`
found struct `ethers::prelude::PendingTransaction<'_, <M as ethers::prelude::Middleware>::Provider>
看起来类型不匹配。我如何“强制”send
返回的 PendingTransaction
对象的内部类型与本地 Liquidator
结构的类型相同?
更新:这是我的整个 liquidator.rs 文件。
您的复杂示例可以简化为:
struct Container<T>(T);
fn put_into_container<T, I>(container: &mut Container<T>, mut iterator: I)
where I: Iterator
{
container.0 = iterator.next().unwrap();
}
抛出:
error[E0308]: mismatched types
--> src/lib.rs:6:19
|
3 | fn put_into_container<T, I>(container: &mut Container<T>, mut iterator: I)
| - this type parameter
...
6 | container.0 = iterator.next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
|
= note: expected type parameter `T`
found associated type `<I as Iterator>::Item`
如果不告诉编译器 I::Item
的类型,它就无法知道它与 T
的类型相同。我们必须像这样明确地告诉它:
struct Container<T>(T);
fn put_into_container<T, I>(container: &mut Container<T>, mut iterator: I)
where I: Iterator<Item = T> // now compiles!
{
container.0 = iterator.next().unwrap();
}
同样,在您的示例中,您试图将 M::Provider
推入 P
而没有向编译器保证它们实际上是同一类型。你可以通过改变这个来做到这一点:
impl<'a, M, P> Liquidator<'a, M, P>
where
M: Middleware + 'a,
P: JsonRpcClient + 'a,
{
// etc
}
进入这个:
impl<'a, M, P> Liquidator<'a, M, P>
where
M: Middleware<Provider = P> + 'a,
P: JsonRpcClient + 'a,
{
// etc
}
应该允许代码编译。
我有以下结构:
pub struct Liquidator<'a, P> {
// ...
pending_liquidations: HashMap<Address, PendingTransaction<'a, P>>,
// ...
}
其中 PendingTransaction
是从 ethers-rs 导入的结构:
pub struct PendingTransaction<'a, P> {
// ...
provider: &'a Provider<P>,
// ...
}
我正在实例化我的 Liquidator
结构并试图在 pending_transactions
中插入一个元素:
pub async fn do_something(&mut self, borrower: &Address) {
// ...
let pending_tx = contract_call.send().await?;
self.pending_liquidations.entry(*borrower).or_insert(pending_tx);
}
(这里是send
方法的definition)。
但代码无法编译:
error[E0308]: mismatched types
--> liquidator/src/liquidator.rs:115:70
|
24 | impl<'a, P> Liquidator<'a, P>
| - this type parameter
...
115 | self.pending_liquidations.entry(*borrower).or_insert(pending_tx);
| ^^^^^^^^^^ expected type parameter `P`, found associated type
|
= note: expected struct `ethers::prelude::PendingTransaction<'a, P>`
found struct `ethers::prelude::PendingTransaction<'_, <M as ethers::prelude::Middleware>::Provider>
看起来类型不匹配。我如何“强制”send
返回的 PendingTransaction
对象的内部类型与本地 Liquidator
结构的类型相同?
更新:这是我的整个 liquidator.rs 文件。
您的复杂示例可以简化为:
struct Container<T>(T);
fn put_into_container<T, I>(container: &mut Container<T>, mut iterator: I)
where I: Iterator
{
container.0 = iterator.next().unwrap();
}
抛出:
error[E0308]: mismatched types
--> src/lib.rs:6:19
|
3 | fn put_into_container<T, I>(container: &mut Container<T>, mut iterator: I)
| - this type parameter
...
6 | container.0 = iterator.next().unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^ expected type parameter `T`, found associated type
|
= note: expected type parameter `T`
found associated type `<I as Iterator>::Item`
如果不告诉编译器 I::Item
的类型,它就无法知道它与 T
的类型相同。我们必须像这样明确地告诉它:
struct Container<T>(T);
fn put_into_container<T, I>(container: &mut Container<T>, mut iterator: I)
where I: Iterator<Item = T> // now compiles!
{
container.0 = iterator.next().unwrap();
}
同样,在您的示例中,您试图将 M::Provider
推入 P
而没有向编译器保证它们实际上是同一类型。你可以通过改变这个来做到这一点:
impl<'a, M, P> Liquidator<'a, M, P>
where
M: Middleware + 'a,
P: JsonRpcClient + 'a,
{
// etc
}
进入这个:
impl<'a, M, P> Liquidator<'a, M, P>
where
M: Middleware<Provider = P> + 'a,
P: JsonRpcClient + 'a,
{
// etc
}
应该允许代码编译。