gpt4 book ai didi

rust - 将特征对象用于结构-错误: wrong number of type arguments

转载 作者:行者123 更新时间:2023-12-03 11:43:51 25 4
gpt4 key购买 nike

我是Rust的新手,使用“Trait Object”时遇到了问题...
现在,我有带有App字段的panels结构,这是实现WavePanel特性的Panel结构的Vec。
由于我有更多实现Panel的工具,因此我希望panels变得更通用。
因此,我尝试将Panel指定为该字段的Trait对象,但是它不起作用...。
这是当前的外观(更改之前):
https://github.com/minagawah/perlin-experiment/blob/6e8064140daedc0767733898621c951619ff4467/src_for_wasm/perlin-wave/src/app.rs#L14

use crate::panels::wave::WavePanel;
use crate::panels::Panel;

#[derive(Clone, Debug)]
pub struct App {
points: Vec<Point>,
points_prev: Vec<Point>,
panels: Vec<WavePanel>, // <-- `WavePanel` struct works just fine.
}

impl App {
pub fn new(config: &Config) -> Result<Self, String> {
let color: String = config.color.clone();
let color2: String = config.color2.clone();

let mut panels = vec![];
for panel in &config.panels {
let id = panel.id.clone();
match id.as_str() {
"wave" => {
panels.push(WavePanel::new(
id.as_str(),
color.as_str(),
color2.as_str(),
)?);
}
_ => {}
}
}

Ok(App {
points: vec![],
points_prev: vec![],
panels: panels,
})
}
}
这是 Panel特性:
pub trait Panel<G: Graphics> {
fn g(&self) -> Rc<RefCell<G>>;

fn reset(&mut self) {
if let Ok(mut g) = self.g().try_borrow_mut() {
let (width, height) = g.size();
g.reset(width, height);
};
}
}
这是 WavePanel实现 Panel特性的方式:
#[derive(Clone, Debug)]
pub struct WavePanel {
id: String,
g: Rc<RefCell<WaveGraphics>>,
graph_type: Rc<Cell<GraphType>>,
}

impl Panel<WaveGraphics> for WavePanel {
fn g(&self) -> Rc<RefCell<WaveGraphics>> {
self.g.clone()
}
}
而且,这是我尝试过的内容(之后):
use crate::panels::wave::WavePanel;
use crate::panels::Panel;

#[derive(Clone, Debug)]
pub struct App {
points: Vec<Point>,
points_prev: Vec<Point>,
panels: Vec<Box<dyn Panel>>, // <-- This does not work...
}

impl App {
pub fn new(config: &Config) -> Result<Self, String> {
let color: String = config.color.clone();
let color2: String = config.color2.clone();

let mut panels = vec![];
for panel in &config.panels {
let id = panel.id.clone();
match id.as_str() {
"wave" => {
// Pushing it into Box this time.
panels.push(Box::new(
WavePanel::new(
id.as_str(),
color.as_str(),
color2.as_str(),
)?
));
}
_ => {}
}
}

Ok(App {
points: vec![],
points_prev: vec![],
panels: panels,
})
}
}
这是错误:
error[E0107]: wrong number of type arguments: expected 1, found 0
--> src/app.rs:15:25
|
15 | panels: Vec<Box<dyn Panel>>,
| ^^^^^ expected 1 type argument

error: aborting due to previous error

For more information about this error, try `rustc --explain E0107`.
error: could not compile `perlin-wave`
Box<dyn Panel>应该不够明确吗?
尝试了很多东西,但仍然没有运气...
拜托,我迫切需要您的帮助。
编辑:已解决(2021.3.4)
对于trait对象的错误使用,kmdreko是正确的。我所拥有的特征不是 Panel而是 Panel<G: Graphics>,它们是完全不同的。
如kmdreko所述,我停止将 G喂给 Panel特质,然后将 G替换为 dyn Graphics(对于 g字段),这就是问题!
它解决了最初的错误。
但是,又出现了另一个问题。
当我实际将派生 WavePanel特性的 Panel结构推到 panels: Vec<Box<dyn Panel>>时,出现了错误消息: expected trait object "dyn Panel", found struct "WavePanel"。这是关于实现异构vec的问题,这不是kmdreko的错。至于原始问题,kmdreko的答案应该是正确的答案。
为此,我在 here中找到了解释。
因此,这与Rust本地推断 WavePanel结构而不是 dyn Panel Trailt对象有关。就在我创建 Box::new(WavePanel::new(..))时,现在我明确告诉我要特征对象 Vec<Box<dyn Panel>>,并对其进行了修复。
还有另一个问题。
由于它与主题相关,因此我认为值得一提。
所以,我现在在 g中有一个 Panel字段,现在在 dyn Graphics中有 G而不是 Panel。现在 Graphics特征也发生了类似的情况。就像我对 WavePanel特质使用 Panel结构一样,我对 WaveGraphics特质也使用 Graphics结构。在某种程度上,Rust现在与 g中定义的 Panel字段的类型混淆了。为此,我决定派生 Any特性的 Graphics特性。只要我定义 as_any_mut()始终返回 Any特质中的 Graphics结构,当我实际要使用它(例如 g.draw())时,我总是可以将trait对象转换为 Any,并执行此操作: g.as_any_mut().downcast_mut::<WaveGraphics>()
对于最后的差异(用于所有修复),找到 here

最佳答案

Shouldn't Box<dyn Panel> be explicit enough?


不,您已将 Panel定义为通用; Panel<A>Panel<B>是不同的特征。如果您希望使用 Panel而不管图形类型如何,则不能通用。
如果 g()仅在支持 reset()的位置,则可以将其删除:
pub trait Panel {
fn reset(&mut self);
}

impl Panel for WavePanel {
fn reset(&mut self) {
if let Ok(mut g) = self.g.try_borrow_mut() {
let (width, height) = g.size();
g.reset(width, height);
};
}
}
或者,如果仍然需要 g()来获取一般的图形对象,则也可以使其动态化:
pub trait Panel {
fn g(&self) -> Rc<RefCell<dyn Graphics>>;
// ^^^^^^^^^^^^

fn reset(&mut self) {
if let Ok(mut g) = self.g().try_borrow_mut() {
let (width, height) = g.size();
g.reset(width, height);
};
}
}

impl Panel for WavePanel {
fn g(&self) -> Rc<RefCell<dyn Graphics>> {
self.g.clone()
}
}

关于rust - 将特征对象用于结构-错误: wrong number of type arguments,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66405385/

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