Проблемы с полиморфизмом и универсальностью при использовании черт - PullRequest
1 голос
/ 20 января 2020

Я пытаюсь использовать универсальность и полиморфизм в Rust с использованием черт, но столкнулся с проблемой.

Это моя общая функция c:

pub fn show<T: graphics::Drawable + std::clone::Clone>(
    core: &mut crate::core::Core,
    image: &T,
    layer: usize,
) {
    let this_image = image.clone();
    let my_box = std::boxed::Box::new(this_image);
    core.layers.layers[layer].push(my_box);
}

Когда я пытаюсь его скомпилировать:

error[E0310]: the parameter type `T` may not live long enough
  --> src/display.rs:23:36
   |
20 | pub fn show<T: graphics::Drawable + std::clone::Clone>(core:&mut crate::core::Core,image:&T,layer:usize){
   |             -- help: consider adding an explicit lifetime bound `T: 'static`...
...
23 |     core.layers.layers[layer].push(my_box);
   |                                    ^^^^^^
   |

Установка времени жизни 'static не поможет с тех пор, как оно отклонит мою основную программу:

error[E0597]: `animated` does not live long enough
  --> src/main.rs:33:29
   |
33 |     display::show(&mut core,&animated,1);
   |     ------------------------^^^^^^^^^---
   |     |                       |
   |     |                       borrowed value does not live long enough
   |     argument requires that `animated` is borrowed for `'static`
34 | }
   | - `animated` dropped here while still borrowed

У меня все еще есть проблемы с пониманием когда дело доходит до времени жизни ...

Я воспроизвел проблему на Rust Playground :

struct A {}

impl SomeRandomTrait for A {}

struct B {}

impl SomeRandomTrait for B {}

struct Container {
    array: [std::boxed::Box<dyn SomeRandomTrait>; 50],
}

trait SomeRandomTrait {}

pub fn foo<T: SomeRandomTrait + std::clone::Clone>(core: &Container, a: &T, index: usize) {
    let a2: T = a.clone();
    let my_box = std::boxed::Box::new(a2);
    core.array[index] = my_box;
}

Когда задание для core.array закомментировано, программа компилируется, но когда она не закомментирована, она не компилируется:

error[E0310]: the parameter type `T` may not live long enough
  --> src/lib.rs:18:25
   |
15 | pub fn foo<T: SomeRandomTrait + std::clone::Clone>(core: &Container, a: &T, index: usize) {
   |            -- help: consider adding an explicit lifetime bound `T: 'static`...
...
18 |     core.array[index] = my_box;
   |                         ^^^^^^
   |
note: ...so that the type `T` will meet its required lifetime bounds
  --> src/lib.rs:18:25
   |
18 |     core.array[index] = my_box;
   |                         ^^^^^^

Я посмотрел с rust-gdb и убедился, что clone работает, а a2 - совершенно другая переменная, чем a1, поэтому я полагаю, что при присваивании массиву не должно быть ошибок.

1 Ответ

0 голосов
/ 24 января 2020

Пожалуйста, проверьте, что одно:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=8b4cdd750565085ae6b455e214bdb774

Вы должны ограничить T, чтобы не хранить в качестве поля любую не статическую ссылку c.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...