I am writing a function to do DNS resolution on a hostname, but I don't quite understand what is happening.
The function I wrote is below:
fn resolve_host(host: &str) -> Option<IpAddr> {
let either_addresses: io::Result<Vec<IpAddr>> =
(host, 0).to_socket_addrs()
.map(|iter| iter.map(|socket_address| socket_address.ip()).collect());
if let Ok(addresses) = either_addresses {
addresses.first().clone() // this line here is the issue
} else {
None
}
}
But if I do this, I get a compiler error:
|
45 | fn resolve_host(host: &str) -> Option<IpAddr> {
| -------------- expected `std::option::Option<std::net::IpAddr>` because of return type
...
51 | addresses.first().clone()
| ^^^^^^^^^^^^^^^^^^^^^^^^^ expected enum `std::net::IpAddr`, found reference
|
= note: expected type `std::option::Option<std::net::IpAddr>`
found type `std::option::Option<&std::net::IpAddr>`
I don't get why this happens. I wrote a small program to try to replicate it, but I get different results. The one below compiles just fine.
fn main() {
let addr = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
let some_addr: Option<&IpAddr> = Some(addr);
println!("{:?}", some_addr.clone());
}
What is it that is incorrect in my resolve_host
function?
I worked around it by replacing the problematic line with Some(addresses.first().unwrap().clone())
,
but this is quite ugly