Как функция может требовать, чтобы тип реализовывал черту, не удаляя существующую границу черты? - PullRequest
0 голосов
/ 04 мая 2018

Я пытаюсь получить main_func, который возвращает вектор типа T структур с признаком SrObject

struct TestA {
    value: u8,
}

pub trait SrObject {
    fn myfunc(&mut self);
}
impl SrObject for TestA {
    fn myfunc(&mut self) {
        unimplemented!();
    }
}
impl Default for TestA {
    fn default() -> TestA {
        TestA { value: 3u8 }
    }
}

fn main_func<T: SrObject>(t: T) -> Vec<T> {
    let mut v = Vec::<T>::new();
    for i in 0..10 {
        v.push(T::default());
        //v[i].myfunc();
    }
    return v;
}

дает:

error[E0599]: no function or associated item named `default` found for type `T` in the current scope
  --> src/main.rs:22:16
   |
22 |         v.push(T::default());
   |                ^^^^^^^^^^ function or associated item not found in `T`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `default`, perhaps you need to implement it:
           candidate #1: `std::default::Default`

Я понимаю, что у меня нет черты Default в fn main_func<T: SrObject>, но как мне добиться этого, не удаляя черту SrObject?

1 Ответ

0 голосов
/ 04 мая 2018

Я бы посоветовал вам вернуться и перечитать Язык программирования Rust . Это бесплатная онлайн-книга, созданная сообществом Rust, которая охватывает широкий спектр того, что вам нужно знать, чтобы стать успешным программистом Rust.

В этом случае в главе о чертах упоминается об границах черт :

Мы можем указать несколько границ признаков для универсального типа, используя +. Если нам нужно было использовать форматирование отображения для типа T в функции, а также метод summary, мы можем использовать границы черты T: Summarizable + Display. Это означает, что T может быть любого типа, который реализует как Summarizable, так и Display.

Для вашего случая:

fn main_func<T: SrObject + Default>() -> Vec<T> {
    (0..10).map(|_| T::default()).collect()
}

Или

fn main_func<T>() -> Vec<T>
where
    T: SrObject + Default,
{
    (0..10).map(|_| T::default()).collect()
}

Другие изменения, чтобы сделать его идиоматическим:

  • Не указывайте тип v при вызове Vec::new; это будет выведено.
  • Не используйте явный return в конце функции.
  • Используйте Iterator::map и Iterator::collect, чтобы преобразовать итератор в коллекцию, вместо того, чтобы толкать элементы вручную.

Смотри также:

...