为什么在我的方法签名中使用 hyper::Client 时会出现错误 "wrong number of type arguments"?

Why do I get the error "wrong number of type arguments" when I use hyper::Client in my method signature?

我想得到一个根据 URL 方案配置的 hyper::Client。为此,我创建了一个小方法:

extern crate http; // 0.1.8
extern crate hyper; // 0.12.7
extern crate hyper_tls; // 0.1.4

use http::uri::Scheme;
use hyper::{Body, Client, Uri};
use hyper_tls::HttpsConnector;

#[derive(Clone, Debug)]
pub struct Feed;

impl Feed {
    fn get_client(uri: Uri) -> Client {
        match uri.scheme_part() {
            Some(Scheme::HTTP) => Client::new(),
            Some(Scheme::HTTPS) => {
                let https = HttpsConnector::new(4).expect("TLS initialization failed");
                let client = Client::builder().build::<_, Body>(https);
            }
            _ => panic!("We don't support schemes other than HTTP/HTTPS"),
        }
    }
}

当我尝试编译它时,我收到此错误消息:

error[E0243]: wrong number of type arguments: expected at least 1, found 0
  --> src/main.rs:13:32
   |
13 |     fn get_client(uri: Uri) -> Client {
   |                                ^^^^^^ expected at least 1 type argument

我不明白为什么它不能编译因为

我做错了什么?

hyper::Client 采用类型参数。您可以在关联的函数调用中省略它们 Client::new(),因为编译器会推导它们,但不会在函数签名中这样做。

您希望 return 类型为 Client<HttpConnector, Body>

问题在于您的构建器方法 return 是 Client<HttpsConnector, Body>,这是不同的。您可能必须定义自己的特征以通过连接器进行抽象。

查看 documentation for Client: Client is a generic type,它取决于两个类型参数:连接器类型 C 和可选主体类型 B。您需要指定哪些类型参数适用于您 return 的 Client,但在您的特定情况下,您似乎想要 return Client<HttpConnector>Client<HttpsConnector> 取决于 URI 方案。你不能那样做,期间。

根据您打算如何使用 get_client 函数,您可以将 return 值包装在 enum:

enum MyClient {
    HttpClient (Client<HttpConnector>),
    HttpsClient (Client<HttpsConnector>),
}
impl MyClient {
    pub fn get(&self, uri: Uri) -> ResponseFuture {
        match self {
            HttpClient (c) => c.get (uri),
            HttpsClient (c) => c.get (uri),
        }
    }
}

fn get_client(uri: Uri) -> MyClient { /* … */ }

或者你可以定义一个特征,为 Client<HttpConnector>Client<HttpsConnector> 实现它,并有 get_client return 你的特征的盒装实例,比如:

trait MyClient {
    pub fn get(&self, uri: Uri) -> ResponseFuture;
}
impl<C> MyClient for Client<C> {
    pub fn get(&self, uri: Uri) -> ResponseFuture {
        Client<C>::get (&self, uri)
    }
}

fn get_client(uri: Uri) -> Box<MyClient> { /* … */ }