我正在尝试减少代码中的样板文件,我已经尝试使用Cow、Borrow或AsRef将这些实现组合在一起,但是编译器抱怨Address没有实现trait sized。
要实现所有的case &str vs String和Address vs &Address,我当前的代码感觉有些多余
pub struct Address(String);
impl From<String> for Address {
fn from(bytes: String) -> Self {
Self(String::from_utf8(Vec::from(bytes)).unwrap())
}
}
impl From<String> for &Address {
fn from(bytes: String) -> Self {
&Address(String::from_utf8(Vec::from(bytes)).unwrap())
}
}
impl From<&str> for Address {
fn from(str: &str) -> Self {
Self(str.to_string())
}
}
impl From<&str> for &Address {
fn from(str: &str) -> Self {
&Address(str.to_string())
}
}
impl<'b> Into<&'b str> for Address {
fn into(self) -> &'b str {
self.0.as_str()
}
}
impl<'b> Into<&'b str> for &Address {
fn into(self) -> &'b str {
self.0.as_str()
}
}
impl<'b> Into<String> for Address {
fn into(self) -> String {
self.0.to_string()
}
}
impl<'b> Into<String> for &Address {
fn into(self) -> String {
self.0.to_string()
}
}
2条答案
按热度按时间xzv2uavs1#
您可能只需要以下四个impls:
kuarbcqp2#
String::from_utf8(Vec::from(bytes)).unwrap()
没有意义。bytes
在您的例子中已经是UTF8字符串,所以这整行是多余的。您的意思是bytes是Vec<u8>
吗?impl From<X> for &Address
没有意义。引用不拥有对象,必须有人拥有Address
对象。impl From<X> for Address
是您真正想要的并且已经拥有的对象。impl Into<&str>
是没有意义的,Into
取得所有权。你不能消费一个对象,然后返回对它的引用。同样,必须有人拥有它。你可能需要AsRef<str>
和Deref<Target=str>
。impl Into<String> for &Address
也不常见。AsRef<str>
和Deref<Target=str>
对于几乎所有情况都足够了,如果您需要消耗转换,请使用impl From<Address> for String
。从不实现Into
,始终实现From
。(From
隐含Into
)所以我会这么做:
下面是如何执行转换,这与通常的Rust行为一致: