Sea*_*act 2 ip-address pattern-matching rust
我想net::Ipv4Addr::LOCALHOST在模式匹配时使用常量过滤掉 IPv4 localhost 地址:
use get_if_addrs; // 0.5.3
use std::net;
fn main() -> std::io::Result<()> {
assert_eq!(
"127.0.0.1".parse::<net::Ipv4Addr>().unwrap(),
net::Ipv4Addr::LOCALHOST
);
{
let ifaces = get_if_addrs::get_if_addrs().unwrap();
for iface in ifaces {
match iface.addr {
get_if_addrs::IfAddr::V4(get_if_addrs::Ifv4Addr {
ip: _,
netmask: _,
broadcast: None,
}) => (),
get_if_addrs::IfAddr::V4(get_if_addrs::Ifv4Addr {
ip: net::Ipv4Addr::LOCALHOST,
netmask: _,
broadcast: _,
}) => (),
get_if_addrs::IfAddr::V4(addr) => println!("{:?}", addr),
get_if_addrs::IfAddr::V6(_) => (),
}
}
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误
use get_if_addrs; // 0.5.3
use std::net;
fn main() -> std::io::Result<()> {
assert_eq!(
"127.0.0.1".parse::<net::Ipv4Addr>().unwrap(),
net::Ipv4Addr::LOCALHOST
);
{
let ifaces = get_if_addrs::get_if_addrs().unwrap();
for iface in ifaces {
match iface.addr {
get_if_addrs::IfAddr::V4(get_if_addrs::Ifv4Addr {
ip: _,
netmask: _,
broadcast: None,
}) => (),
get_if_addrs::IfAddr::V4(get_if_addrs::Ifv4Addr {
ip: net::Ipv4Addr::LOCALHOST,
netmask: _,
broadcast: _,
}) => (),
get_if_addrs::IfAddr::V4(addr) => println!("{:?}", addr),
get_if_addrs::IfAddr::V6(_) => (),
}
}
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
std::net::Ipv4Addr确实有PartialEqand 的实现Eq,那么这个错误是什么意思?我该如何解决?
正如错误消息所述:
必须注释
#[derive(PartialEq, Eq)]
这不适用于Ipv4Addr,它手动实现它,而不是派生它。
相反,使用匹配守卫:
use get_if_addrs; // 0.5.3
fn main() -> std::io::Result<()> {
let ifaces = get_if_addrs::get_if_addrs().unwrap();
for iface in ifaces {
match iface.addr {
get_if_addrs::IfAddr::V4(get_if_addrs::Ifv4Addr {
broadcast: None, ..
}) => (),
get_if_addrs::IfAddr::V4(get_if_addrs::Ifv4Addr { ip, .. }) if ip.is_loopback() => (),
get_if_addrs::IfAddr::V4(addr) => println!("{:?}", addr),
get_if_addrs::IfAddr::V6(_) => (),
}
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
你也可以考虑引入一些嵌套:
use get_if_addrs::{IfAddr, Ifv4Addr}; // 0.5.3
fn main() -> std::io::Result<()> {
let ifaces = get_if_addrs::get_if_addrs().unwrap();
for iface in ifaces {
match iface.addr {
IfAddr::V4(addr) => match addr {
Ifv4Addr {
broadcast: None, ..
} => (),
Ifv4Addr { ip, .. } if ip.is_loopback() => (),
addr => println!("{:?}", addr),
},
IfAddr::V6(_) => (),
}
}
Ok(())
}
Run Code Online (Sandbox Code Playgroud)
RFC 1445更详细地解释了基本决策:
- 引入
#[structural_match]可应用于结构或枚举的功能门控属性,T以指示T可以在模式中使用类型的常量。- 已
#[derive(Eq)]自动将此属性应用于它装饰的结构或枚举。自动插入的属性不需要使用特征门。- 将 struct 或 enum 类型的常量扩展为等效模式时,要求 struct 或 enum 类型用
#[structural_match]. 内置类型的常量总是被扩展的。这些变化的实际效果会防止模式的使用的常数的,除非这些常数的类型是一个内置型(如
i32或&str),或者用户定义的常数,其Eq被衍生(不仅仅是实现)。
| 归档时间: |
|
| 查看次数: |
371 次 |
| 最近记录: |