這是我一直在努力的代碼
use ethers_providers::{Provider, Http}; //, JsonRpcClient};
// this doesn't work
// trait ClientGeneric<T> {
// fn get_client(&self, url:&str) -> Provider<T> {
// Provider::<T>::try_from(url).unwrap()
// }
// }
// this works but I want generic
trait ClientConcrete {
fn get_client(&self, url:&str) -> Provider<Http> {
Provider::<Http>::try_from(url).unwrap()
}
}
struct Test;
impl ClientConcrete for Test {}
#[cfg( test )]
mod tests {
use super::*;
// #[test]
// fn test_get_client_generic() {
// let test = Test{};
// let client = test.get_client("http://localhost:8080");
// }
#[test]
fn test_get_client_concrete() {
let test = Test{};
let client = test.get_client("http://localhost:8080");
}
}
我想Provider<T>為每個傳輸 T?? 回傳:http、ws、ipc、mock 等 通常每個傳輸都實作了 TryFrom 特征。然而,上面的代碼不適用于通用 T,即使它適用于具體傳輸。我得到的通用 T 錯誤:
error[E0277]: the trait bound `Provider<T>: From<&str>` is not satisfied
--> src/test.rs:6:9
|
6 | Provider::<T>::try_from(url).unwrap()
| ^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&str>` is not implemented for `Provider<T>`
|
= help: the following other types implement trait `TryFrom<T>`:
<Provider<Http> as TryFrom<&'a String>>
<Provider<Http> as TryFrom<&str>>
<Provider<Http> as TryFrom<String>>
= note: required because of the requirements on the impl of `Into<Provider<T>>` for `&str`
= note: required because of the requirements on the impl of `TryFrom<&str>` for `Provider<T>`
不幸的是,沒有關于型別 TI 的 match 陳述句可以使用(如在 Golang 中)去具體型別實作。據我了解,我無法TryFrom<&str>為 foreign struct實作 foreign trait Provider<T>。TryFrom<&str>為基礎型別實作Http,,WsIpc實作
還有什么我可以做的嗎?
uj5u.com熱心網友回復:
這是您無法編譯的通用函式:
fn get_client(&self, url:&str) -> Provider<T> {
Provider::<T>::try_from(url).unwrap()
}
它不編譯的原因是T沒有指定任何邊界。如果編譯,則意味著該函式可以Provider<T>為任何 T. 但這是不可能的;正如你所注意到的,只有某些型別,比如Httpwork for T,因為Provider<Http>實作TryFrom<&str>。因此,您需要提供這些必要的界限,以便函式可以編譯。
我是這樣寫的:
use std::fmt::Debug;
use ethers_providers::Provider;
trait ClientGeneric<T>
where
for<'a> &'a str: TryInto<Provider<T>>,
for<'a> <&'a str as TryInto<Provider<T>>>::Error: Debug,
{
fn get_client(&self, url: &str) -> Provider<T> {
url.try_into().unwrap()
}
}
impl<T, U> ClientGeneric<U> for T
where
for<'a> &'a str: TryInto<Provider<U>>,
for<'a> <&'a str as TryInto<Provider<U>>>::Error: Debug,
{
}
struct Test;
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_get_client_generic() {
let test = Test {};
let _client = test.get_client("http://localhost:8080");
}
}
注意我選擇使用TryInto而不是TryFrom,盡管在這種情況下兩者都可以正常作業。
第一個界限讓我們呼叫try_into()將 轉換&str為 ( Result-wrapped) Provider<T>:
for<'a> &'a str: TryInto<Provider<T>>
只需要第二個界限,因此該.unwrap()方法有效:
for<'a> <&'a str as TryInto<Provider<T>>>::Error: Debug
在實際代碼中,您可能應該避免展開,而是回傳一個Result.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/525661.html
標籤:仿制药锈
