当字符串存储为String
而不是&str
时,它无法实现特征ToSocketAddrs
。最接近的是impl<'a> ToSocketAddrs for (&'a str, u16)
。
use std::net::TcpStream;
fn main() {
let url = "www.google.com".to_string(); // String
let url2 = "www.google.com"; // &'static str
let port = 80;
// Does not work
let tcp = TcpStream::connect((url, port));
// Works
let tcp2 = TcpStream::connect((url2, port));
}
这失败了:
error[E0277]: the trait bound `(std::string::String, {integer}): std::net::ToSocketAddrs` is not satisfied
--> src/main.rs:9:11
|
9 | let tcp = TcpStream::connect((url, port));
| ^^^^^^^^^^^^^^^^^^ the trait `std::net::ToSocketAddrs` is not implemented for `(std::string::String, {integer})`
|
= help: the following implementations were found:
<(std::net::Ipv6Addr, u16) as std::net::ToSocketAddrs>
<(std::net::Ipv4Addr, u16) as std::net::ToSocketAddrs>
<(&'a str, u16) as std::net::ToSocketAddrs>
<(std::net::IpAddr, u16) as std::net::ToSocketAddrs>
= note: required by `std::net::TcpStream::connect`
为了实现String
特征,我如何将&str
强制转换为ToSocketAddrs
?从Rust 1.0的文档中,我认为String
会自动转移到&str
。
答案 0 :(得分:8)
String
不会强制转换为&str
,因为根据RFC 0401,特征匹配时自动deref强制不起作用。因此,在这种情况下使用简单的&url
不会起作用,因为自动deref不会应用于它。您没有获得&str
,而是获得&String
,而ToSocketAddrs
没有匹配的impl。但是,您可以使用取消引用运算符显式地导致deref。特别是,&*url
应该有效。 (&url[..]
也有效,因为[..]
是&#34的语法;对所有内容进行切片&#34;,但它有点冗长。)
答案 1 :(得分:4)
由于std::net::ToSocketAddrs
仅在(&str, _)
上实现,您需要使用&url[..]
切片语法来获取字符串的一部分:
let tcp = TcpStream::connect((&url[..], port));