如何构造实现自引用泛型Framework trait的Frame枚举实例?
Rust自引用泛型Trait实现的实例构造问题
我是Rust新手,目前陷入困境。我定义了枚举Frame,它实现了包含自引用泛型T和关联类型C的Framework trait,代码除测试函数it_works中的构造行外均可正常编译,但我不知道如何构造Frame的新实例,恳请帮助,也欢迎指出设计问题。
原始代码:
use std::collections::HashMap; use std::sync::Arc; type Error = "String"; pub enum Value<T> { Boolean(bool), String("String"), Object(Arc<dyn Object<T>>), Null, } pub type R = Result<(), Error>; pub type Rv<T> = Result<Arc<Value<T>>, Error>; pub trait Object<T: Framework> { fn name(&self) -> &str; fn get(&self, m: &mut T, n: &str) -> Rv<T>; } pub trait Framework<T = Self> { type C: Clone; fn context(&self) -> Option<Self::C>; fn process(&mut self, input: Arc<Value<T>>) -> Rv<T>; } pub struct FrameBase<T, C: Clone> { ctx: Option<C>, consts: HashMap<usize, Arc<Value<T>>>, } impl<T: Framework, C: Clone> FrameBase<T, C> { pub fn new() -> Self { Self { ctx: None, consts: HashMap::<usize, Arc<Value<T>>>::new(), } } } pub enum Frame<T: Framework, C: Clone> { Overlay(Box<Frame<T, C>>, FrameBase<T, C>), Base(FrameBase<T, C>), } impl<T: Framework, C: Clone> Frame<T, C> { pub fn new_base(ctx: C) -> Self { let base = FrameBase::<T, C> { ctx: Some(ctx), consts: HashMap::<usize, Arc<Value<T>>>::new(), }; Self::Base(base) } } impl<T: Framework, C: Clone> Framework for Frame<T, C> { type C = C; fn context(&self) -> Option<Self::C> { match self { Self::Overlay(_, base) => match &base.ctx { Some(x) => Some(x.clone()), None => None, }, Self::Base(base) => match &base.ctx { Some(x) => Some(x.clone()), None => None, }, } } fn process(&mut self, _input: Arc<Value<Frame<T, C>>>) -> Rv<Frame<T, C>> { let null = Value::Null; Ok(Arc::new(null)) } } #[cfg(test)] mod tests { // use std::sync::Arc; use super::{Frame, FrameBase, Framework, Value}; #[test] fn it_works() { // HERE! // TODO: How to construct a new instance of Frame? let frame = Frame::<, isize>::new_base(0); } }
更新:感谢提示,查阅文档后发现,若在 crate 中启用associated_type_defaults特性,可实现自引用。修改后的代码如下:
trait Framework { type T = Arc<Self>; type C: Clone; type S: Storage<Value<Self::T>>; fn context(&self) -> Option<Self::C>; fn process(&self, store: &mut Self::S, input: Arc<Value<Self::T>>) -> Rv<Self::T>; }
修改后的代码现已可正常运行。
内容的提问来源于stack exchange,提问作者Yun Luo
相关产品推荐
相关产品推荐

