【问题标题】:How to return a struct with a generic type that implements the `Read` and `Write` traits?如何返回具有实现“Read”和“Write”特征的泛型类型的结构?
【发布时间】:2017-04-03 05:20:37
【问题描述】:

我试图将TcpStreamTlsStream 包装在一个对象中,以便我可以使用一个结构与它们中的任何一个进行交互。我正在尝试根据配置值将 io 方法委托给一个或另一个,但无法弄清楚如何返回具有实现 ReadWrite 特征的泛型类型的结构

我的代码如下

pub struct TcpStream<T: Read + Write> {
    io_delegate: T,
    config: Config,
}

impl<T> TcpStream<T>
    where T: Read + Write
{
    pub fn connect<A: ToSocketAddrs>(config: Config, addr: A) -> io::Result<TcpStream<T>> {
        let tcp_stream = net::TcpStream::connect(addr).unwrap();
        if config.ssl {
            let tls_stream = TlsConnector::builder()
                .unwrap()
                .build()
                .unwrap()
                .connect("rem", tcp_stream)
                .unwrap();
            return Ok(TcpStream {
                          config: config,
                          io_delegate: tls_stream,
                      });
        }
        return Ok(TcpStream {
                      config: config,
                      io_delegate: tcp_stream,
                  });
    }
}

当我尝试编译时出现以下错误

error[E0308]: mismatched types
  --> src/rem/tcp_stream.rs:19:23
   |
19 |               return Ok(TcpStream {
   |  _______________________^ starting here...
20 | |                 config: config,
21 | |                 io_delegate: tls_stream
22 | |             });
   | |_____________^ ...ending here: expected type parameter, found struct `native_tls::TlsStream`
   |
   = note: expected type `rem::tcp_stream::TcpStream<T>`
              found type `rem::tcp_stream::TcpStream<native_tls::TlsStream<std::net::TcpStream>>`

error[E0308]: mismatched types
  --> src/rem/tcp_stream.rs:24:19
   |
24 |           return Ok(TcpStream{
   |  ___________________^ starting here...
25 | |                 config: config,
26 | |                 io_delegate: tcp_stream
27 | |         });
   | |_________^ ...ending here: expected type parameter, found struct `std::net::TcpStream`
   |
   = note: expected type `rem::tcp_stream::TcpStream<T>`
              found type `rem::tcp_stream::TcpStream<std::net::TcpStream>`

有没有办法实现这种事情?

【问题讨论】:

  • 如果您有兴趣返回 trait,请参阅 stackoverflow.com/q/27535289/155423
  • 对于您的错误,请参阅stackoverflow.com/questions/31490913/…
  • @Shepmaster OP 正在尝试在一个分支中返回 TlsStream 并在另一个分支中返回 TcpStream,impl Trait 无济于事。与stackoverflow.com/questions/31490913/… 的关系非常微妙,虽然答案确实提到了 trait 对象,但导致错误的问题与这个不同。
  • @kennytm impl Trait 是第一个答案中的 4 种可能性之一;另一个是返回一个盒装的 trait 对象。并且返回一个盒装的特征对象是 OP 所做的。我不清楚;为什么你认为它不是重复的?而且我看不出第二个问题有什么用处;这是 OP 遇到的确切问题 - 该函数说它返回调用者选择的任何 T,但实现忽略它并返回一个具体类型。

标签: rust


【解决方案1】:

我不确定这是否是最佳解决方案,但它似乎确实有效。

我创建了一个新的特征,它是 Read + Write 的组合,然后将它作为一个 Box 存储在我的结构中

trait ReadWrite : Read + Write {}

impl<T: Read + Write> ReadWrite for T {}

pub struct TcpStream{
    io_delegate : Box<ReadWrite>,
    config: Config
}

impl TcpStream {

    pub fn connect<A: ToSocketAddrs>(config: Config, addr: A) -> TcpStream {
        let tcp_stream = net::TcpStream::connect(addr).unwrap();
        if config.ssl {
            let tls_stream = TlsConnector::builder().unwrap().build().unwrap().connect("rem", tcp_stream).unwrap();
            return TcpStream {
                config: config,
                io_delegate: Box::new(tls_stream)
            };
        }
        return TcpStream{
                config: config,
                io_delegate:Box::new(tcp_stream)
        };
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 2023-01-12
    • 2022-11-23
    • 2018-02-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多