rust - 如何为 UnixStream 和 TcpStream 创建多态类型
问题描述
我有一个名为 Connection 的结构,它接收 atokio::net::TcpStream
或 atokio::net::UnixStream
以与远程服务器对话。鉴于 Rust 没有构造函数,我在我的结构中添加了一个静态 new() 方法并在那里执行身份验证握手,然后将流的实例传递给 Connection 的新实例并将其从 new() 返回给我的最终用户。
我的问题是如何创建一个可以设置为 UnixStream 或 TcpStream 的临时文件,以便我可以在进行握手的消息交换期间对其进行操作。由于 UnixStream 和 TcpStream 没有共同的父级,我不知道如何实现这一点:
pub struct Configuration {
tcp_socket: Option<SocketAddr>,
unix_socket: Option<PathBuf>,
}
pub(crate) struct Connection {
tcp: Option<TcpStream>,
unix: Option<UnixStream>,
}
impl Connection {
pub(crate) async fn new(configuration: &Configuration) -> Result<Connection, Box<dyn std::error::Error>> {
let mut stream;
if configuration.unix_socket().is_some() {
stream = UnixStream::connect(configuration.unix_socket().unwrap()).await?;
} else {
stream = TcpStream::connect(configuration.tcp_socket().unwrap()).await?;
}
// Handshake code goes here...
let conn = Connection {
tcp: Some(stream),
unix: None,
};
Ok(conn)
}
解决方案
您可以使用这样的枚举:
pub(crate) enum Connection{
Tcp(TcpStream),
Unix(UnixStream),
}
并且match
无论您在哪里访问它或为具有通用功能的两个流实现一个特征。这个特征可以被视为一个泛型,它将在编译时评估它是哪个版本。
最小的例子:
pub(crate) trait ExampleStream{
fn connect<A>(address: A) -> Result<Self, Error>;
}
enum 选项最接近您到目前为止所写的内容,因此我建议您这样做。
推荐阅读
- prometheus - 检查 ufw 状态并在未激活时发送 Prometheus 警报
- javascript - 想用更好的算子优化 Airtable 查询
- nuget-package-restore - NuGetAuthenticate 管道失败,无法获取本地颁发者证书
- docker - docker push to private registry 失败“服务器向 HTTPS 客户端提供 HTTP 响应”
- javascript - 画布上最后绘制的线是实心的?
- google-sheets - 如何避免必须将 0 放入 NULL 字段以在 Google 表格中获得正确的查询计算
- .net - Web 浏览器自动刷新崩溃
- asp.net-core - 以分块形式发送响应时,Asp.net 核心端点“挂起”
- swift - 如何根据 CollectionViewController 中的滚动距离移动到下一个单元格?
- sql-server - Azure-SSIS IR 部署:项目的目标服务器版本不受支持