简体   繁体   中英

Can I return a slice of a &str input if the return type is generic?

Suppose I'm writing a function which trims whitespace around a &str and then parses it to a generic type (this is a simplified example: my real function is grabbing several capture groups from a regex).

fn trim_and_parse<T: FromStr>(s: &str) -> T {
  s.trim().parse().unwrap()
}

so I could do for example

let n: u32 = trim_and_parse("  24  ");
let inner: String = trim_and_parse("  hi ");

This works great, but that second one is allocating a new String . I'd really like it if I could return a slice of the input instead:

let inner: &str = trim_and_parse("  hi ");

This doesn't work because &str isn't FromStr , and I'm not sure it would really make sense for it to be. Is there anything I can do to make this interface work, so that if I use eg u32 as the type parameter then it parses the trimmed string into a number, but I can use something else as the type parameter to get a slice of the original string instead?

I tried experimenting with something like

trait MyFromStr {
    fn from_str(s: &str) -> Self;
}

impl MyFromStr for &str {
    fn from_str(s: &str) -> Self {
        s
    }
}

which gets a lifetime may not live long enough which is fair enough. Is there another way to make this work?

You can do that by declaring the trait to have a lifetime:

trait MyFromStr<'a>: Sized {
    type Err;
    fn from_str(s: &'a str) -> Result<Self, Self::Err>;
}

impl<'a> MyFromStr<'a> for &'a str {
    type Err = std::convert::Infallible;
    fn from_str(s: &'a str) -> Result<Self, Self::Err> {
        Ok(s)
    }
}

impl<'a> MyFromStr<'a> for i32 {
    type Err = std::num::ParseIntError;
    fn from_str(s: &'a str) -> Result<Self, Self::Err> {
        s.parse()
    }
}

fn trim_and_parse<'a, T: MyFromStr<'a>>(s: &'a str) -> T
where
    T::Err: std::fmt::Debug,
{
    MyFromStr::from_str(s.trim()).unwrap()
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM