在Rust中,很容易创建IpAddr一个IpV4Addr:
let ipv4 = IpV4Addr::new(127,0,0,1);
let ip = IpAddr::V4(ipv4);
Run Code Online (Sandbox Code Playgroud)
但似乎没有办法回来:
if ip.is_ipv4() {
let ipv4: IpV4Addr = .....?
}
Run Code Online (Sandbox Code Playgroud)
原因是我需要在某个时刻(通过IPv4::octets)访问IPv4地址的八位字节以通过网络传输它们.但是,我想IpAddr在应用程序的其他部分使用更通用的表示,因为我希望将来实现IPv6,因此使网络代码不是特定于IPv4的.
IpAddr是IP地址的抽象.它是一个枚举,它包含一个Ipv4Addr或Ipv6Addr一些方法来提供对它们的抽象访问.
Rust不会让你投入IpAddr到一个Ipv4Addr因为它实际上是Ipv6Addr什么?你也必须处理这个案子.你说服Rust,你已经处理了所有的可能性match.
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
fn main() {
let ips = [
IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
IpAddr::V6(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)),
];
for ip in ips.iter() {
match *ip {
IpAddr::V4(ip4) => println!("ipv4: {}, octets: {:?}", ip4, ip4.octets()),
IpAddr::V6(ip6) => println!("ipv6: {}, segments: {:?}", ip6, ip6.segments()),
}
}
}
Run Code Online (Sandbox Code Playgroud)
不需要默认情况,因为Rust类型检查器知道没有其他可能性.ips是一个数组,IpAddr只包含两种可能性,V4或V6.事实上,如果你把一个放在那里,Rust会发出警告,所以如果IpAddr将来发生变化,你会发现编译错误.
IpAddr 是一个枚举,因此您可以使用模式匹配:
if let IpAddr::V4(ipv4) = ip {
// here ipv4 is of type IpV4Addr
}
// or, if you need to handle IPv6 as well
match ip {
IpAddr::V4(ipv4) => { /* handle IPv4 */ }
IpAddr::V6(ipv6) => { /* handle IPv6 */ }
}
Run Code Online (Sandbox Code Playgroud)
此外,IpAddris Copy,因此您甚至不必担心消耗其原始值(ip变量),它只会为您隐式复制。
| 归档时间: |
|
| 查看次数: |
640 次 |
| 最近记录: |