【问题标题】:Rust struct field generic over Deref<Target=Self>Deref<Target=Self> 上的 Rust 结构字段泛型
【发布时间】:2020-12-25 19:17:17
【问题描述】:

我正在尝试构建操作递归(树状)数据结构的 Rust 代码。天真地,可以将其定义为

struct ALinkedList {
    value: i32,
    next: Option<Box<Self>>
}

为了试验不同的内存布局并将算法设计与存储分开,我想将定义概括为类似

struct ALinkedList<D: Deref<Target=Self>> {
    value: i32,
    next: Option<D>
}

但是在尝试构造 ALinkedList 的实例时,我得到了

64 |     let t: ALinkedList<Box<_>> = ALinkedList{value: 0, next: Some(Box::new(ALinkedList{value: 0, next: None}))};
   |            ^^^^^^^^^^^^^^^^^^^ cyclic type of infinite size

我的问题是:

  1. 是否可以让这些递归类型定义在 Rust 中工作?
  2. 如果不是,我可以使用哪些其他设计模式来表示树状结构,而无需硬编码其子项在内存中的存储和取消引用方式?

【问题讨论】:

    标签: rust


    【解决方案1】:

    不幸的是,Rust 目前无法处理无限深的泛型。

    有一种使用 GAT(通用关联类型)的方法,不幸的是仍然只在夜间使用 (playground):

    #![feature(generic_associated_types)]
    use std::ops::Deref;
    
    struct ALinkedList<A: Allocator> {
        value: i32,
        next: Option<A::Allocated<Self>>
    }
    impl<A: Allocator> ALinkedList<A> {
        fn set_next(&mut self, next: Self) {
            self.next = Some(next.into()) // create a new allocation via From
        }
    }
    
    trait Allocator {
        type Allocated<T>: Deref<Target=T> + From<T>;
    }
    
    struct BoxAllocator;
    impl Allocator for BoxAllocator {
        type Allocated<T> = Box<T>;
    }
    
    fn main() {
        let mut t: ALinkedList<BoxAllocator> = ALinkedList{value: 0, next: Some(Box::new(ALinkedList{value: 0, next: None}))};
        t.set_next(ALinkedList{value: 1, next: None});
    }
    

    【讨论】:

    • allocate trait 方法似乎没有在您的代码中的任何地方使用
    • 它旨在成为从 LinkedList impl 中创建分配的方式。看着它,我认为使用 From 更清洁。更新了代码并添加了有关其工作原理的示例。
    • 谢谢!我一直在玩这个并试图用枚举替换结构,在某些情况下它就像你的示例一样工作正常,但在其他情况下它无法编译:playground。具体来说,enum CLinkedList&lt;A: Allocator&gt; { Head, Next(A::Allocated&lt;Self&gt;) } 编译失败并抛出 overflow evaluating the requirement '...: Sized' 。这是由于 GAT 不完整导致的编译器错误,还是我对大小有误解?
    • 这确实是一个奇怪的错误。对我来说看起来像一个错误,提交一个 Rust 问题!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 1970-01-01
    相关资源
    最近更新 更多