rust - 使用 Struct 的特征对象 - 错误:类型参数的数量错误
问题描述
我是 Rust 的新手,我在使用“Trait Object”时遇到了问题......
现在,我有App
带有字段的结构,它是实现特征panels
的结构的 Vec 。
由于我有更多的实现,我想变得更通用。
所以,我尝试指定为该字段的特征对象,但它不起作用....WavePanel
Panel
Panel
panels
Panel
这是它目前的样子(更改之前):
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
but Panel<G: Graphics>
,它们完全不同。
正如 kmdreko 提到的,我停止喂食G
trait Panel
,我G
用dyn Graphics
(for the field g
) 替换,这就成功了!
它解决了最初的错误。
但是,出现了另一个问题......
当我实际将WavePanel
派生Panel
trait 的结构推送到 时panels: Vec<Box<dyn Panel>>
,我收到错误消息:expected trait object "dyn Panel", found struct "WavePanel"
. 这是实现异构vec的问题,不是kmdreko的错。就所关注的原始问题而言,kmdreko 的答案应该是正确的答案。
为此,我在这里找到了解释。
所以,这是关于 RustWavePanel
在本地推断结构而不是dyn Panel
trailt 对象。就在我创建的时候Box::new(WavePanel::new(..))
,现在我明确地告诉我我想要特征对象Vec<Box<dyn Panel>>
,并且它修复了它。
还有另一个问题....
由于它与主题有关,我认为也值得留下一个便条...
所以,我现在拥有的领域g
是 in而不是in 。trait现在也发生了类似的情况。就像我有struct for trait 一样,我有struct for trait。在某种程度上,Rust 现在与...中定义的字段类型混淆了。对于这个问题,我决定为 trait 派生 trait 。只要我定义总是在 trait 中返回struct ,当我真正想使用它时,例如,我总是可以将 trait 对象转换为,并执行以下操作:Panel
dyn Graphics
G
Panel
Graphics
WavePanel
Panel
WaveGraphics
Graphics
g
Panel
Any
Graphics
as_any_mut()
Any
Graphics
g.draw()
Any
g.as_any_mut().downcast_mut::<WaveGraphics>()
.
对于最终差异(对于所有修复),可在此处找到。
解决方案
不够
Box<dyn Panel>
明确吗?
不,您已定义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()
}
}
推荐阅读
- angular - 如何以角度将方法从一个组件调用到另一个组件
- java - Java中char数组的选择排序
- javascript - 改进功能以突出显示所有类型的搜索词 - 反应原生
- visual-studio - 无法下载 Visual Studio 安装程序
- java - 线程“main”java.lang.NumberFormatException 中的异常:对于输入字符串:“3727284434”
- gnuplot - 避免在 gnuplot 中剪切轴编号
- excel - 使用 B 列中的 Excel 数据搜索网站;将搜索结果保存在 C 和 D 列中
- javascript - 如何仅在按下输入按钮时禁用表单提交
- python - 有什么好主意来衡量用户在队列中等待的时间吗?(Python)
- highcharts - HighStock 不绘制注释/注释离开视口?