如何将IpAddr转换为IPv4Addr?

Phi*_*wig 3 rust

在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的.

Sch*_*ern 7

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将来发生变化,你会发现编译错误.


Vla*_*eev 5

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变量),它只会为您隐式复制。