简体   繁体   English

如何在 Rust 中使用 trait bound?

[英]How do I use trait bound in Rust?

I am going to use generic to pass A<B<C>>>> and Z<A<B<C>>>> to a function as one type.我将使用generic将 A<B<C>>>> 和 Z<A<B<C>>>> 作为一种类型传递给函数。 But I don't know how to implement trait bounds for this.但我不知道如何为此实现trait bounds The detail are as follows.详情如下。

http service and https service each have listener and poll for accept. http服务和https服务都有监听器和轮询接受。 When an accept request comes in, handle_request() is called to process the request.当一个接受请求进来时, handle_request()被调用来处理这个请求。

The http and https request processing methods are the same, but in the case of https , TlsService is additionally implemented to include tls processing. httphttps请求处理方法是一样的,但是在https的情况下,额外实现了TlsService以包含tls处理。 As a result, it has the following structure:因此,它具有以下结构:

pub type RawRequest = HttpService<AccessLog<RouteService<CorsService<ProxyService>>>>;

pub struct Services {
    http_service: Arc<RawRequest>,
    https_service: Arc<TlsService<RawRequest>>,
    http_accept_service: AcceptService,
    https_accept_service: AcceptService,
}

...

fn handle_request<S>(stream: TcpStream, accesslog_sender: crossbeam_channel::Sender<String>, http_service: S) {
    let connection = NewConnection {
        stream,
        service_builder: ServiceBuilder::new(),
    };

    tokio::spawn(async move {
        ACCESSLOG_SENDER
            .scope(accesslog_sender, async move {
                if let Err(_e) = http_service.call(connection).await {
                    // TODO: write error
                };
            })
            .await;
    });
}

handle_request(stream, accesslog_sender, services.http_accept_service.clone());
handle_request(stream, accesslog_sender, services.https_accept_service.clone());

Question问题

I am going to use generic to call the same function for different types of Service.我将使用泛型为不同类型的服务调用相同的函数。

fn handle_request<S>(
    stream: TcpStream,
    accesslog_sender: crossbeam_channel::Sender<String>,
    http_service: S,
) {
      ...
}

But I get a trait bound error.但我得到一个特征绑定错误。

error[E0599]: no method named `call` found for type parameter `S` in the current scope

I'm new to Rust and I'm struggling with generic and trait bound .我是 Rust 的新手,我正在为generictrait bound苦苦挣扎。 Please help me how to write请帮我怎么写

When you use a generic type like S rust will not make any assumptions about that type (expect that it has a compile time known size).当您使用像S这样的泛型类型时,rust 不会对该类型做出任何假设(期望它具有已知的编译时间大小)。 Therefore you cannot really do anything on that type.因此,您实际上无法在该类型上做任何事情。 For the compiler there is no way to know that a call() method exists.对于编译器,无法知道call()方法是否存在。

This is different from how C++ handles generics where you would get long and hard to read compiler errors when using a type for S which does not have all the functionality used by the generic function.这与 C++ 处理泛型的方式不同,当使用不具有泛型函数使用的所有功能的S类型时,您将获得冗长且难以阅读的编译器错误。

The solution in Rust is a trait . Rust 中的解决方案是trait Lets suppose both your http and https service have a call function.假设您的 http 和 https 服务都具有call功能。 You can then write a trait (or more likely use one from the library your using) which says that these types have a call method.然后,您可以编写一个特征(或更可能使用您使用的库中的一个),说明这些类型有一个call方法。 You can then use this trait as a trait bound in your function like this: handle_request<S : Name_of_the_trait>然后,您可以将此特征用作函数中的trait bound ,如下所示: handle_request<S : Name_of_the_trait>

This tells the compiler to only use types as a substitute for S which implement Name_of_the_trait and therefore you can call all the functions of this trait on S .这告诉编译器仅使用类型来替代实现Name_of_the_traitS ,因此您可以在S上调用此 trait 的所有函数。

I guess you should read more about traits and it should become apparent what you should do in detail.我想您应该阅读更多有关特征的信息,并且应该清楚您应该详细做什么。 https://doc.rust-lang.org/stable/book/ch10-00-generics.html https://doc.rust-lang.org/stable/book/ch10-00-generics.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM