我有以某种方式转换字符串引用的代码,例如采取第一个字母
trait Tr {
fn trim_indent(self) -> Self;
}
impl<'a> Tr for &'a str {
fn trim_indent(self) -> Self {
&self[..1] // some transformation here
}
}
fn main() {
let s = "aaa".trim_indent();
println!("{}", s);
}
现在我尝试将此代码概括为实现AsRef<str>
的任何特定类型。我的最后一次尝试是
use std::ops::Deref;
trait Tr<'a> {
fn trim_indent(self) -> Deref<Target = str> + 'a + Sized;
}
impl<'a, T: AsRef<str>> Tr<'a> for T {
fn trim_indent(self) -> Deref<Target = str> + 'a + Sized {
self.as_ref()[..1] // some transformation here
}
}
fn main() {
let s = "aaa".trim_indent();
println!("{}", s);
}
我被卡住了因为没有Sized
我在编译时遇到类型未知的错误,但是Size
我得到一个错误,我无法明确使用标记特征。
答案 0 :(得分:2)
无论您从哪种类型开始,&str
切片的最终类型始终为&str
,因此您的返回类型必须为&str
。
然后,实现特征引用类型的问题,以便您可以将输入和输出生命周期联系在一起:
use std::rc::Rc;
trait Tr<'a> {
fn trim_indent(self) -> &'a str;
}
impl<'a, T> Tr<'a> for &'a T
where
T: AsRef<str> + 'a,
{
fn trim_indent(self) -> &'a str {
&self.as_ref()[..1] // Take the first **byte**
}
}
fn main() {
let s: &str = "aaa";
println!("{}", s.trim_indent());
let s: Box<str> = Box::from("bbb");
println!("{}", s.trim_indent());
let s: Rc<str> = Rc::from("ccc");
println!("{}", s.trim_indent());
}
在这种情况下,由于您列出的所有类型都会实现Deref
,因此您只需实现&str
的特征,所有类型都可以使用它:
trait Tr {
fn trim_indent(&self) -> &str;
}
impl Tr for str {
fn trim_indent(&self) -> &str {
&self[..1]
}
}
另见: