Rust 根据编译目标OS,将不同类型的值分配给变量的惯用方法是什么?

Rust 根据编译目标OS,将不同类型的值分配给变量的惯用方法是什么?,rust,compiler-errors,compilation,rust-cargo,rust-tokio,Rust,Compiler Errors,Compilation,Rust Cargo,Rust Tokio,我正在研究一个绑定到Tokio套接字并管理TCP连接的代码库。在生产中,它使用板条箱绑定到AF_VSOCK 在Mac上本地开发时,AF_VSOCKAPI不可用,因为没有hypervisor->VM连接-它只是使用cargo run本地运行 在本地运行时,我创建了一个标准结构,在生产中我创建了一个标准结构。这两种结构基本上是可互换的,并且公开了相同的方法。不管使用哪个结构,代码的其余部分都可以完美地工作 到目前为止,我只保留了这两个结构,并简单地注释掉了本地不需要的结构-这显然不是“好的实践”。我

我正在研究一个绑定到Tokio套接字并管理TCP连接的代码库。在生产中,它使用板条箱绑定到
AF_VSOCK

在Mac上本地开发时,
AF_VSOCK
API不可用,因为没有
hypervisor->VM
连接-它只是使用
cargo run
本地运行

在本地运行时,我创建了一个标准结构,在生产中我创建了一个标准结构。这两种结构基本上是可互换的,并且公开了相同的方法。不管使用哪个结构,代码的其余部分都可以完美地工作

到目前为止,我只保留了这两个结构,并简单地注释掉了本地不需要的结构-这显然不是“好的实践”。我的代码如下:

#[tokio::main]
异步fn main()->结果{
//生产AF_VSOCK侦听器(本地注释)
让mut listener=tokio_vsock::VsockListener::bind(
&SockAddr::Vsock(
VsockAddr::新建(
VMADDR_CID_ANY,
听着!,
)
)
)
.expect(“无法绑定AF_VSOCK侦听器”);
//本地TCP侦听器(在生产中注释掉)
让mut listener=tokio::net::TcpListener::bind(
std::net::SocketAddress::新建(
std::net::IpAddr::V4(
std::net::Ipv4Addr::new(0,0,0,0)
),
监听端口为u16,
)
)
.等待
.expect(“无法绑定TCP侦听器”);
//无论使用哪种侦听器,这都有效
让mut incoming=listener.incoming();
而让一些(套接字)=传入的.next().等待{
火柴插座{
正常(mut流)=>{
//做点什么
}
}
}
好(())
}
我试过使用
cfg!()
宏,将
target_os
设置为条件,但编译器抱怨两个
bind()
方法返回的类型不匹配


我的问题是:根据编译目标操作系统的不同,为变量分配不同类型的不同值的惯用方法是什么?

有多个选项。关于stdlib本身的用法,最简单也是最常见的一种是使用
#[cfg]
宏(而不是
cfg!()
)。下面的代码片段阐明了它的用法:

struct-Linux;
嵌入式Linux{
fn x(&self)->Linux{
println!(“Linux”);
Linux
}
}
结构窗口;
impl窗口{
fn x(&self)->Windows{
println!(“窗口”);
窗户
}
}
fn main(){
#[cfg(不是(target_os=“linux”)]
设obj={
让obj=Linux;
obj
};
#[cfg(非(target_os=“windows”)]
设obj={
设obj=Windows;
obj
};
设uj=obj.x();
}
(见附件)

在您的情况下,这将是(未经测试):

#[tokio::main]
异步fn main()->结果{
#[cfg(target_os=“linux”)]
让mut listener=tokio_vsock::VsockListener::bind(
&SockAddr::Vsock(
VsockAddr::新建(
VMADDR_CID_ANY,
听着!,
)
)
)
.expect(“无法绑定AF_VSOCK侦听器”);
#[cfg(target_os=“Mac”)]
让mut listener=tokio::net::TcpListener::bind(
std::net::SocketAddress::新建(
std::net::IpAddr::V4(
std::net::Ipv4Addr::new(0,0,0,0)
),
监听端口为u16,
)
)
.等待
.expect(“无法绑定TCP侦听器”);
...
}
检查可用条件,包括功能标志,以防目标操作系统不够适用


#[cfg]
cfg!()
之间的主要区别在于
cfg!
不会删除代码。根据它的文档:“cfg!与#[cfg]不同,它不会删除任何代码,并且只计算为true或false”。因此,使用
#[cfg]时会出现编译错误
更类似于C/C++中的if-def并删除未使用的代码,因此编译器永远不会发现类型不匹配。

创建一个trait,为两个结构实现它,然后使用cfg创建适当的结构,用作trait对象。替代方法:枚举,再次有条件创建。另外,请提供可编译代码,最好是指向操场。谢谢!我不知道
#[cfg]
cfg!()
之间的区别,在您的解释之后,这更有意义-非常感谢:)