在Rust中,通常的做法是让函数更喜欢字符串切片&str
,而不是借来的字符串&String
,因为String
类型实现了Deref<Target = str>
。
我想知道是否有一种惯用的方法来实现一个结构体的From<&str>
特性,使得该结构体可以从字符串切片或借来的字符串中创建。我能想到的最好的例子如下:
pub struct Base64 {
bytes: Vec<u8>
}
impl From<&str> for Base64 {
fn from(s: &str) -> Self {
Base64 { bytes: base64::decode(s).unwrap() }
}
}
impl From<&String> for Base64 {
fn from(s: &String) -> Self {
Base64::from(s as &str)
}
}
不使用Base64::from(&String::from("..."))
这样的最后一个函数会产生以下错误:
the trait bound `Base64: From<&String>` is not satisfied
the following other types implement trait `From<T>`:
<Base64 as From<&str>>
确实有一种更简洁的方法:
impl<T: Deref<Target=str>> From<&T> for Base64 {
fn from(s: &T) -> Self {
let s = s as &str;
Base64 { bytes: base64::decode(s).unwrap() }
}
}
并去掉另外两个性状隐含。这一个使用泛型与trait边界:现在任何可以解引用到str
可以与你的结构体使用。
编辑:或者,保留&str
的非通用版本,放弃String
版本,然后像这样调用它:
Base64::from(String::from("...").as_ref())
这将缓解@kmdreko指出的担忧