gpt4 book ai didi

rust - 来自引用的特征对象

转载 作者:行者123 更新时间:2023-12-05 02:35:36 26 4
gpt4 key购买 nike

下面是(大致)取自 rust 书第 17.2 章的特征对象示例。对于我的用例,我想在创建 screen 后继续使用 buttonselect_box (请参阅注释掉的 println!() 在声明 screen 之后),但是我不能,因为 buttonselect_box 被移动到 screen .在我看来,解决方案似乎是让 screen 借用 select_boxscreen,而不是取得所有权。但是,我不知道该怎么做。我试过从以下引用创建框:

let screen = Screen {
components: vec![Box::new(&select_box), Box::new(&button)],
};

但这会产生如下错误:

the trait `Draw` is not implemented for `&SelectBox`
fn main() {
let select_box = SelectBox {
width: 75,
height: 10,
options: vec![
String::from("Yes"),
String::from("Maybe"),
String::from("No"),
],
};
let button = Button {
width: 50,
height: 10,
label: String::from("OK"),
};
let screen = Screen {
components: vec![Box::new(select_box), Box::new(button)],
};
// println!("button width: {}", button.width);
screen.run();
}

trait Draw {
fn draw(&self);
}

struct Screen {
components: Vec<Box<dyn Draw>>,
}

impl Screen {
fn run(&self) {
for component in self.components.iter() {
component.draw();
}
}
}

struct Button {
width: u32,
height: u32,
label: String,
}

impl Draw for Button {
fn draw(&self) {
println!("Button({}, {}, {})", self.width, self.height, self.label)
}
}

struct SelectBox {
width: u32,
height: u32,
options: Vec<String>,
}

impl Draw for SelectBox {
fn draw(&self) {
println!(
"SelectBox({}, {}, {})",
self.width,
self.height,
self.options.join(";")
)
}
}

最佳答案

通常的解决方案是对 &T&mut T 进行全面实现,其中 T: Draw:

impl<T: ?Sized + Draw> Draw for &'_ T {
fn draw(&self) {
<T as Draw>::draw(&**self)
}
}
impl<T: ?Sized + Draw> Draw for &'_ mut T {
fn draw(&self) {
<T as Draw>::draw(&**self)
}
}

但是,你会得到另一个错误:

error[E0597]: `select_box` does not live long enough
--> src/main.rs:17:35
|
17 | components: vec![Box::new(&select_box), Box::new(&button)],
| ---------^^^^^^^^^^^-
| | |
| | borrowed value does not live long enough
| cast requires that `select_box` is borrowed for `'static`
...
21 | }
| - `select_box` dropped here while still borrowed

error[E0597]: `button` does not live long enough
--> src/main.rs:17:58
|
17 | components: vec![Box::new(&select_box), Box::new(&button)],
| ---------^^^^^^^-
| | |
| | borrowed value does not live long enough
| cast requires that `button` is borrowed for `'static`
...
21 | }
| - `button` dropped here while still borrowed

这是因为dyn Trait实际上是dyn Trait + 'static。您需要添加生命周期参数:

struct Screen<'a> {
components: Vec<Box<dyn Draw + 'a>>,
}

impl Screen<'_> {

Playground .

关于rust - 来自引用的特征对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70496032/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com