/ / Як функція може вимагати, щоб тип реалізував ознаку, не видаляючи наявну прикмету? - дженерики, структура, іржа, риси, тип-параметр

Як функція може вимагати, щоб тип виконував рису, не знімаючи існуючу ознаку? - генерики, структура, іржа, риси, тип-параметр

Я намагаюся мати main_func що повертає вектор типу T конструкції з a 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 риса у фн main_func<T: SrObject>, але як я можу досягти цього, не видаляючи SrObject риса?

Відповіді:

4 для відповіді № 1

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

У цьому випадку, розділ про риси згадує це про межі рис:

Ми можемо вказати кілька меж ознак для загального типу за допомогою +. Якщо нам потрібно було мати можливість використовувати форматування дисплея для типу T у функції, а також summary метод, ми можемо використовувати межі ознак T: Summarizable + Display. Це означає T може бути будь-якого типу, що реалізує обидва Summarizable і Display.

Для вашої справи:

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

Or

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

Інші зміни, щоб зробити його ідіоматичним:

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

Дивись також: