简体   繁体   English

从功能返回特征

[英]Return Traits from function

I've take a look to rust lib: https://github.com/cyderize/rust-websocket/ In source file https://github.com/cyderize/rust-websocket/blob/master/src/client/response.rs I seen method begin(): 我看一下生锈lib: https//github.com/cyderize/rust-websocket/源文件https://github.com/cyderize/rust-websocket/blob/master/src/client/response .rs我看到方法begin():

pub fn begin(self) -> Client<DataFrame, Sender<W>, Receiver<R>> {
    let (reader, writer) = self.into_inner();
    let sender = Sender::new(writer);
    let receiver = Receiver::new(reader);
    Client::new(sender, receiver)
}

So... I've decide to create some simple wrapper function: 所以......我决定创建一些简单的包装函数:

fn get_transport(url: &str)  ->  Client<DataFrame, Sender<Write>, Receiver<Read>> {
    let url = Url::parse(url).unwrap();
    let request = Client::connect(url).unwrap();
    let response = request.send().unwrap();
    let mut ws = response.begin();

    ws
}

But unfortunately I've got error result: 但不幸的是我有错误的结果:

error: the trait `core::marker::Sized` is not implemented for the type `websocket::ws::sender::Sender<std::io::Write>` [E0277]
src/lib.rs:36 fn get_transport(url: &str)  ->  Client<DataFrame, Sender<Write>, Receiver<Read>> {

Could some one please describe me why I could not return value in this way. 有人可以形容我为什么不能以这种方式回报价值。 What the difference with begin() method in the response.rs ? response.rs中的begin()方法有什么区别? How should I return value in my case? 在我的情况下,我应该如何回报价值?

UPD1: After @ker recommendations I've have next code: UPD1:在@ker推荐之后我有下一个代码:

fn get_transport<W: Write, R: Read, S: Sender<W>, RE: Receiver<R>>(url: &str) -> Client<DataFrame, S, RE> {

    let url = Url::parse(url).unwrap();
    let request = Client::connect(url).unwrap();
    let response = request.send().unwrap();
    let mut ws = response.begin();

    ws
}

But next error received in next compilation: 但是在下一次编译中收到下一个错误:

src/lib.rs:45:5: 45:7 error: mismatched types:
 expected `websocket::client::Client<websocket::dataframe::DataFrame, S, RE>`,
    found `websocket::client::Client<websocket::dataframe::DataFrame, websocket::client::sender::Sender<websocket::stream::WebSocketStream>, websocket::client::receiver::Receiver<websocket::stream::WebSocketStream>>`
(expected type parameter,
    found struct `websocket::client::sender::Sender`) [E0308]
src/lib.rs:45     ws
                  ^~
src/lib.rs:45:5: 45:7 help: run `rustc --explain E0308` to see a detailed explanation
error: aborting due to previous error

Seems I'v use wrong Sender and wrong Receiver :\\ After corrections to use section I've have got result code: 似乎我使用错误的发件人和错误的接收器:\\经过更正后使用部分我已经得到了结果代码:

fn get_transport(url: &str) -> Client<DataFrame, Sender<WebSocketStream>, Receiver<WebSocketStream>> {
    let url = Url::parse(url).unwrap();
    let request = Client::connect(url).unwrap();
    let response = request.send().unwrap();
    let mut ws = response.begin();

    ws
}

Unfortunately I could not found out why I could not use generics as result value. 不幸的是我无法找出为什么我不能使用泛型作为结果值。 Like this: 像这样:

fn get_transport<R: Read, W: Write>(url: &str) -> Client<DataFrame, Sender<W>, Receiver<R>>

In this caseI receive error message: 在这种情况下我收到错误消息:

expected `websocket::client::Client<websocket::dataframe::DataFrame, websocket::client::sender::Sender<W>, websocket::client::receiver::Receiver<R>>`,
    found `websocket::client::Client<websocket::dataframe::DataFrame, websocket::client::sender::Sender<websocket::stream::WebSocketStream>, websocket::client::receiver::Receiver<websocket::stream::WebSocketStream>>`
(expected type parameter,
    found enum `websocket::stream::WebSocketStream`) [E0308]
src/lib.rs:45     ws
                  ^~

Since any type may implment a trait, you can never know the size of an object by knowing just about the traits it implements. 由于任何类型都可能影响特征,因此您无法通过了解对象实现的特征来了解对象的大小。 What you can do, is make your function generic over the types that implement Write and Read respectively. 你可以做的是,使你的函数分别通用于实现Write和Read的类型。 This way you can return the object, while not knowing what the actual type of the object is. 这样您就可以返回对象,而不知道对象的实际类型是什么。

fn get_transport<W: Write, R: Read, S: Sender<W>, RE: Receiver<R>>(url: &str) -> Client<DataFrame, S, RE> {
    let url = Url::parse(url).unwrap();
    let request = Client::connect(url).unwrap();
    let response = request.send().unwrap();
    let mut ws = response.begin();

    ws
}

The reason why adding generics works, is because the generic labels point to the actual types, without knowing anything about the type except which traits they implement. 添加泛型的原因之一是因为泛型标签指向实际类型,而不知道除了它们实现的特征之外的任何类型。

You want to replace Write and Send in the return type with concrete types. 您希望使用具体类型替换返回类型中的WriteSend

Try changing the line let mut ws = response.begin(); 尝试更改行let mut ws = response.begin(); to let mut ws: () = response.begin() and you will see an error message that will tell you what concrete types are being returned from the begin function. let mut ws: () = response.begin() ,您将看到一条错误消息,告诉您从begin函数返回的具体类型。

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

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