Generics 我如何铸造Rc<;RefCell<;混凝土类型>&燃气轮机;至Rc<;RefCell<;dyn性状>>;?
我试图将Generics 我如何铸造Rc<;RefCell<;混凝土类型>&燃气轮机;至Rc<;RefCell<;dyn性状>>;?,generics,rust,trait-objects,Generics,Rust,Trait Objects,我试图将Rc转换为Rc(数据实现接口),但在通用方法中不可能: use std::cell::RefCell; use std::rc::Rc; trait Interface { fn pouet(&self); } struct Data {} impl Interface for Data { fn pouet(&self) { println!("pouet"); } } fn helper<T&g
Rc
转换为Rc
(数据
实现接口
),但在通用方法中不可能:
use std::cell::RefCell;
use std::rc::Rc;
trait Interface {
fn pouet(&self);
}
struct Data {}
impl Interface for Data {
fn pouet(&self) {
println!("pouet");
}
}
fn helper<T>(o: &Rc<RefCell<T>>)
where
T: Interface,
{
let t = o as &Rc<RefCell<dyn Interface>>;
work(t);
}
fn work(o: &Rc<RefCell<dyn Interface>>) {
o.borrow().pouet();
}
fn main() {
// work
{
let o = Rc::new(RefCell::new(Data {}));
work(&(o as Rc<RefCell<dyn Interface>>));
}
// raise an compile error
{
let o = Rc::new(RefCell::new(Data {}));
helper(&o);
}
}
使用std::cell::RefCell;
使用std::rc::rc;
特征接口{
fn-pouet(和self);
}
结构数据{}
impl数据接口{
fn pouet(和self){
println!(“pouet”);
}
}
fn助手(o:&Rc)
哪里
T:接口,
{
设t=o as&Rc;
工作(t);
}
fn工程(o:&Rc){
o、 借().pouet();
}
fn main(){
//工作
{
设o=Rc::new(RefCell::new(Data{}));
工作(&(o作为Rc));
}
//引发编译错误
{
设o=Rc::new(RefCell::new(Data{}));
助手(&o);
}
}
我在非基本类型转换上有一个编译错误:
error[E0605]:非原语强制转换:`&Rc`as`&Rc`
-->src/main.rs:20:13
|
20 |设t=o as&Rc;
|^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
非常感谢,我理解 解决办法是
fn helper<T>(o: &Rc<RefCell<T>>)
where
T: Interface + 'static,
{
let t = o.clone() as Rc<RefCell<dyn Interface>>;
work(&t);
}
fn助手(o:&Rc)
哪里
T:接口+'静态,
{
设t=o.clone()为Rc;
工作与技术;
}
或
fn助手(o:Rc)
哪里
T:接口+'静态,
{
设t=o为Rc;
工作与技术;
}
感谢与Java等语言不同,对trait对象的强制转换实际上修改了数据(必须添加vtable),这意味着您必须借用refcell。强制转换值并不是简单地重新解释类型,因此您必须实际借用refcell,以便可以对值进行变异。另请参见,问题是,结构只包含它们的数据。例如,
struct Foo{field:u8}
的大小为1字节。但是,为了将我们的对象用作trait对象(将其视为实现trait的随机对象),我们现在必须将其存储在一个函数表中,该函数表描述如何使用它,称为vtable。vtable只是一个表,它指向我们对trait的实现。假设我们有一个traitMyTrait
和一个方法run()
,我们有结构Foo
和Bar
实现MyTrait
,然后我们有一个Vec
包含许多Foo
s和Bar
s。每个trait对象(dyn MyTrait
)必须包含一个指向其版本的run()
的指针,以便我们知道如何调用它。回到问题上来,问题是你需要存储一个指向trait中所有方法的指针表,以便能够使用它。
fn helper<T>(o: Rc<RefCell<T>>)
where
T: Interface + 'static,
{
let t = o as Rc<RefCell<dyn Interface>>;
work(&t);
}