泛型类型特征与结构实现不匹配

时间:2020-01-21 14:16:20

标签: rust traits

我已经将自己放在rustls's GitHub page上的完整示例上。

现在,我想使用该确切的代码并将其封装在Struct中。 Struct应该负责流的创建(在示例中为tls)。 此流是最重要的对象,必须将其存储以供以后读取和写入。

我想出了以下结构和实现:

struct Client<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> {
    tls: rustls::Stream<'a, S, T>,
}

impl<'a, S: 'a + rustls::Session + ?Sized, T: 'a + Read + Write + ?Sized> Client<'a, S, T> {
    fn new(host: &str, port: &str) -> Client<'a, S, T> {
        let mut config = rustls::ClientConfig::new();
        config.root_store.add_server_trust_anchors(&webpki_roots::TLS_SERVER_ROOTS);

        let dns_name = webpki::DNSNameRef::try_from_ascii_str(host).unwrap();
        let mut sess = rustls::ClientSession::new(&Arc::new(config), dns_name);
        let mut sock = TcpStream::connect(format!("{}:{}", host, port)).unwrap();
        let mut tls = rustls::Stream::new(&mut sess, &mut sock);

        Client {
            tls
        }
    }
}

这将导致以下错误:

error[E0308]: mismatched types
  --> src\main.rs:27:13
   |
16 | impl<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> Client<'a, S, T> {      
   |          - this type parameter
...
27 |             tls
   |             ^^^ expected type parameter `S`, found struct `rustls::client::ClientSession`
   |
   = note: expected struct `rustls::stream::Stream<'_, S, T>`
              found struct `rustls::stream::Stream<'_, rustls::client::ClientSession, std::net::TcpStream>`
   = help: type parameters must be constrained to match other types
   = note: for more information, visit https://doc.rust-lang.org/book/ch10-02-traits.html#traits-as-parameters

首先,我不知道如何解决此问题。 根据{{​​3}} rustls::ClientSession确实实现了特征rustls::Session,即S

第二,我担心生命周期将成为一个问题。 (目前无法确认,因为编译器现在仅抱怨类型不匹配。) 所有这些变量均已创建,据我所知,函数返回后将立即销毁所有这些变量。 意味着sesssock也将被销毁,因为它们没有存储在任何地方,并且tls上只有&mut引用(即不存储对象本身)。 我也会像这样存储它们:

struct Client<'a, S: 'a + Session + ?Sized, T: 'a + Read + Write + ?Sized> {
    session: rustls::ClientSession,
    socket: TcpStream,
    tls: rustls::Stream<'a, S, T>,
}
(...)
Client {
  session: sess,
  socket: sock,
  tls
}

尽管这不能解决问题,因为tls现在仍然引用了函数返回时将移动的局部变量(即,再次:指向空指针)。


我该如何解决编译问题?如果生存期成为问题,该如何处理? 此外,存储tls可能是一个错误的决定吗? 到目前为止,我从Rust中学到的是“如果很难做到,那可能是错误的!”。

0 个答案:

没有答案