Rust Book第17章的源代码可能是错误的

问题描述 投票:0回答:1

最初我使用本教程作为一些练习代码的参考。 经过几个小时的故障排除后,我只是简单地按原样尝试了该页面上的代码。

https://doc.rust-lang.org/book/ch17-02-trait-objects.html

pub fn add(left: usize, right: usize) -> usize {
    left + right
}

pub trait Draw {
    fn draw(&self);
}

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

impl Draw for Button {
    fn draw(&self) {
        // code to actually draw a button
    }
}
pub struct Screen<T: Draw> {
    pub components: Vec<T>,
}

impl<T> Screen<T>
where
    T: Draw,
{
    pub fn run(&self) {
        for component in self.components.iter() {
            component.draw();
        }
    }
}

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

impl Draw for SelectBox {
    fn draw(&self) {
        // code to actually draw a select box
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }

    #[test]
    fn test_tell_me(){
        let screen = Screen {
            components: vec![
                Box::new(SelectBox {
                    width: 75,
                    height: 10,
                    options: vec![
                        String::from("Yes"),
                        String::from("Maybe"),
                        String::from("No"),
                    ],
                }),
                Box::new(Button {
                    width: 50,
                    height: 10,
                    label: String::from("OK"),
                }),
            ],
        };
    
        screen.run();
    }
}

错误:

warning: `decision-command-parser` (lib) generated 1 warning

error[E0277]: the trait bound `Box<SelectBox>: Draw` is not satisfied
  --> src/lib.rs:60:25
   |
60 |               components: vec![
   |  _________________________^
61 | |                 Box::new(SelectBox {
62 | |                     width: 75,
63 | |                     height: 10,
...  |
74 | |                 }),
75 | |             ],
   | |_____________^ the trait `Draw` is not implemented for `Box<SelectBox>`
   |
   = help: the following other types implement trait `Draw`:
             Button
             SelectBox

bard.google.com 说我需要将特征添加到按钮,但鉴于它是“书”等,教程应该是事实来源。

rust traits box
1个回答
0
投票

书上讲得很清楚了,我觉得:

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

Screen
结构体上,我们将定义一个名为
run
的方法,它将 在每个
draw
上调用
components
方法,如下所示 示例 17-5:

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

这与定义使用泛型类型的结构不同 具有特征边界的参数。泛型类型参数只能是 一次替换为一种具体类型,而特质对象 允许使用多种具体类型填充特征对象 运行。例如,我们可以使用 a 来定义 Screen 结构体 泛型类型和特征绑定如清单 17-6 所示:

pub struct Screen<T: Draw> {
    pub components: Vec<T>,
}

impl<T> Screen<T>
where
    T: Draw,
{
    pub fn run(&self) {
        for component in self.components.iter() {
            component.draw();
        }
    }
}

这将我们限制为具有组件列表的

Screen
实例 全部为
Button
类型或全部为
TextField
类型。如果你永远 具有同构集合,使用泛型和特征边界是 更可取,因为定义将在编译时单态化 是时候使用具体类型了。

另一方面,使用特征对象的方法,一个

Screen
实例可以保存一个包含
Vec<T>
Box<Button>
以及 一个
Box<TextField>
。让我们看看它是如何工作的,然后我们再讨论 关于运行时性能的影响。

因此,通用方法可用于同构集合,而特征对象方法可用于异构集合。您尝试使用具有多种类型的通用方法,但正如书中所说,它无法做到这一点。

© www.soinside.com 2019 - 2024. All rights reserved.