【发布时间】:2021-09-19 18:48:08
【问题描述】:
在我拥有std::net::TcpStream 或native_tls::TlsStream<TcpStream> 的情况下,我面临动态特征的编译器错误。我的算法思路如下:
- 在 var "tcp" 中创建 TCP 流
- 如果方案是 https => 用新的
TlsStream<TcpStream>替换相同的变量。 - 在流上写入和接收数据。
我需要的重要特征是std::io::Read 和std::io::Write。因此我想,我只是将我的“tcp”变量建模为Box<dyn Read + Write>。但无论我如何尝试,我总是遇到编译错误。您可以在下面看到一个无法编译的最小示例。
use std::net::{IpAddr, Ipv4Addr, TcpStream};
use std::io::{Write as IoWrite, Read as IoRead};
use native_tls::TlsConnector;
fn main() {
let use_https = true;
// IP of "example.com".
let ip_addr = std::net::IpAddr::V4(Ipv4Addr::new(85, 13, 155, 159));
let port = if use_https { 443 } else { 80 };
let tcp_stream = TcpStream::connect((ip_addr, port)).unwrap();
let tcp_stream = maybe_connect_to_tls(tcp_stream, use_https);
}
fn maybe_connect_to_tls(tcp: TcpStream, use_https: bool) -> Box<dyn IoRead + IoWrite> {
if use_https {
let tls = TlsConnector::new().unwrap();
let tcp = tls.connect("example.com", tcp).unwrap();
Box::new(tcp)
} else {
Box::new(tcp)
}
}
这是我尝试编译时遇到的错误:
error[E0225]: only auto traits can be used as additional traits in a trait object
--> src/main.rs:14:78
|
14 | fn maybe_connect_to_tls(tcp: TcpStream, use_https: bool) -> Box<dyn IoRead + IoWrite> {
| ------ ^^^^^^^ additional non-auto trait
| |
| first non-auto trait
|
= help: consider creating a new trait with all of these as super-traits and using that trait here instead: `trait NewTrait: std::io::Read + std::io::Write {}`
= note: auto-traits like `Send` and `Sync` are traits that have special properties; for more information on them, visit <https://doc.rust-lang.org/reference/special-types-and-traits.html#auto-traits>
我也尝试了maybe_connect_to_tls<T>(tcp: TcpStream, use_https: bool) -> Box<T> where T: IoWrite + IoRead + ?Sized,但无论我尝试什么都会导致其他编译失败..
知道如何解决这个问题吗?我想要一个通用的流对象,它应该对应用程序不可见,具体实现是什么。
【问题讨论】:
标签: rust