我有两个需要相互引用的结构。由于其他原因,这些结构需要同时绕过借用检查器。所以我在 *mut T 周围有一个包装器来绕过检查器。现在我试图让每个结构都具有第二个结构的泛型类型。
这是一个玩具示例:
use d2simrs::util::internalref::InternalRef;
pub trait Layer3Trait {
fn foo() {
println!("TraitA::foo()");
}
}
pub trait Layer2Trait {
fn bar() {
println!("TraitB::foo()");
}
}
pub struct SimpleLayer2<Layer3T>
where Layer3T: Layer3Trait
{
pub layer3: InternalRef<Layer3T>,
}
pub struct SimpleLayer3<Layer2T>
where Layer2T: Layer2Trait
{
pub layer2: InternalRef<Layer2T>,
}
pub type Layer2 = SimpleLayer2<Layer3>;
pub type Layer2Ref = InternalRef<Layer2>;
pub type Layer3 = SimpleLayer3<SimpleLayer2<Layer3>>;
pub type Layer3Ref = InternalRef<Layer3>;
InternalRef 的代码是 here
为此我得到了
|
30 | pub type Layer3 = SimpleLayer3<SimpleLayer2<Layer3>>;
| ^^^^^^
|
= note: ...which again requires computing type of `example2::Layer3`, completing the cycle
note: cycle used when computing type of `example2::Layer2`
--> examples/network/bypass_borrow/example2.rs:27:32
|
27 | pub type Layer2 = SimpleLayer2<Layer3>;
| ^^^^^^
我可以以某种方式重新定义某些东西,以便 SimpleLayer2 和 SimpleLayer3 可以相互引用。
最佳答案
Rust 不支持循环泛型类型。如果您有:
pub type Layer2 = SimpleLayer2<Layer3>;
pub type Layer3 = SimpleLayer3<Layer2>;
那么Layer3
的具体类型将是:
SimpleLayer3<SimpleLayer2<SimpleLayer3<SimpleLayer2<SimpleLayer3<SimpleLayer2<SimpleLayer3<SimpleLayer2<SimpleLayer3<SimpleLayer2<SimpleLayer3<...>>>>>>>
这是不允许的。
正如评论中所指出的,如果您的设计是没有循环依赖的继承式设计,那将是理想的,因为它显然可以避免此类问题。但如果这不合适,解决此问题的标准方法是使用 Rc
/Arc
和特征对象,这也将避免您的内部 *mut T
包装器(如果需要可变性,则使用 RefCell
/RwLock
):
use std::rc::{Rc, Weak};
pub struct SimpleLayer2 {
pub layer3: Weak<RefCell<dyn Layer3>>,
}
pub struct SimpleLayer3 {
pub layer2: Rc<RefCell<dyn Layer2>>,
}
请参阅这些其他问题以了解其他潜在的想法:
关于rust - 解决 Rust 中需要相互引用的特征之间的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69433749/