При использовании обобщений в Rust, «размер значений типа` str` не может быть известен во время компиляции " - PullRequest
0 голосов
/ 18 апреля 2020

Следующий код будет работать и печатать Foo("hello"):

#[derive(Debug)]
struct Foo<'a>(&'a str);

impl<'a> From<&'a str> for Foo<'a> {
    fn from(s: &'a str) -> Self {
        Foo(s)
    }
}

fn main() {
    let s: &str = "hello";
    let foo = Foo::from(s);
    println!("{:?}", foo);
}

Однако, если я использую дженерики и заменю все str на T, он не будет работать:

#[derive(Debug)]
struct Foo<'a, T>(&'a T);

impl<'a, T> From<&'a T> for Foo<'a, T> {
    fn from(s: &'a T) -> Self {
        Foo(s)
    }
}

fn main() {
    let s: &str = "hello";
    let foo = Foo::from(s);
    println!("{:?}", foo);
}
error[E0277]: the size for values of type `str` cannot be known at compilation time
  --> a.rs:12:25
   |
2  | struct Foo<'a, T>(&'a T);
   | ------------------------- required by `Foo`
...
12 |     let foo = Foo::from(s);
   |                         ^ doesn't have a size known at compile-time
   |
   = help: the trait `std::marker::Sized` is not implemented for `str`
   = note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

Разве &'a T не эквивалентен &'a str? Почему компилятор использует str вместо &'a str?

1 Ответ

3 голосов
/ 18 апреля 2020

Параметры типа неявно Sized в ржавчине. Вы должны явно добавить ограничение ?Sized.

#[derive(Debug)]
struct Foo<'a, T: ?Sized>(&'a T);

impl<'a, T: ?Sized> From<&'a T> for Foo<'a, T> {
    fn from(s: &'a T) -> Self {
        Foo(s)
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...