【问题标题】:How does Cons save data (Rust Linked List)Cons如何保存数据(Rust Linked List)
【发布时间】:2021-09-05 20:27:05
【问题描述】:

我一直在学习 Rust,并决定做一些基本类型有助于更深入地学习这门语言。

链接列表状态的"Rust by Example" 页面

Ln 4: // 缺点:包含一个元素和一个指向下一个节点的指针的元组结构

我认为这意味着它通过始终使用Cons 填充一个空节点来递归创建列表。

enum linkedList
{
    Head(Head), // Front Pointer and list metrics
    Cons(Arc<linkedList>, isize), //(Data, Next Value) Cons is apparently a LISP construct
    Tail(isize), // Rear Pointer
    Nil //Used to drop the stream
}

我真正的问题是允许数据存储在Arc&lt;linkedList&gt; 节点中的底层机制是什么?我认为需要通用 (&lt;T&gt;) 将数据存储在列表中,但显然这是不正确的。

p.s 我的印象是 ARC 和 BOX 智能指针可以互换,但用于不同的目的。我试图制作一个单端翻转安全链表的线程安全版本,有点像循环队列。

【问题讨论】:

  • 真正的 rust by example 很旧而且很糟糕,请忘记 Rust 中的链表
  • 它肯定不是很好@Stargateur,但我用它来提高我的知识。否则 在性能、内存使用和易用性方面要好得多。不过感谢您的意见!
  • 如果你对链表特别感兴趣,有一整本书适合你:Learn Rust With Entirely Too Many Linked Lists
  • 我不清楚混乱在哪里。您不确定enum T { A(B, C) } 是如何存储其数据的吗?或者Arc 是如何工作的?
  • 我错过了什么吗?您链接的 RbE 页面不包含此 enum 定义。那么这是什么?你自己的发明?您是什么意思“我认为将数据存储在列表中需要通用”... RbE 中的数据只是u32。您是在谈论 RbE 的代码还是您自己的代码?添加HeadTail变体有什么意义?

标签: data-structures rust linked-list cons


【解决方案1】:

您的实现与 Cons 列表的标准定义略有不同。直截了当的定义(类似于在 Lisp 中的定义)是

type Data = isize;

enum List {
    Nil,
    Cons(Box<List>, Data),
}

如您所见,Cons 变体由嵌套列表和此节点数据元素组成。在您的情况下,每个节点都有一个isize

如果你有一个Arc&lt;List&gt;Box&lt;List&gt;,这个嵌套的List 对象也可以是Cons 的变体,并带有另一个isizeArcBox 不关心他们指向什么。


有些事情不太习惯。同时拥有TailNil 变体没有多大意义,因为现在您有两种方法来表示列表结束。同样,让Head 成为列表的变体很奇怪,因为列表的头部只是在开头,但您的实现允许在列表中间使用Head 变体。

最好不要有一个额外的Nil 节点来表示列表的结束。相反,最后一个节点知道它是最后一个(如您的 Tail 变体),因此您没有为空节点​​分配额外的空间。这就是我认为 Rust 中单链表的惯用定义:

struct List {
    // ...
    // extra info for list head
    // ...

    first_node: Option<Box<ListNode>>,
}

struct ListNode {
    value: Data,
    next: Option<Box<ListNode>>,
}

要使这个通用化,我们只需从之前删除我们的类型别名Data 并使其成为通用参数:

struct ListNode<T> {
    value: T,
    next: Option<Box<ListNode<T>>>,
}

关于BoxArcBox 是一个指向堆上值的拥有指针,这意味着只有这个盒子拥有它指向的内存。 ArcRc 的线程安全版本,它是一个引用计数的堆值。可以存在多个指向该内存的Rc-pointers 并读取它,计算这些的数量。因此,所有权可以共享。

您应该根据是否要创建更多指向节点的引用计数指针来选择使用哪个(请注意,您可能希望 Rc&lt;RefCell&lt;Node&gt;&gt;Arc&lt;Mutex&lt;Node&gt;&gt; 在创建列表后也对其进行变异) .如果您只有列表的头部并且想要遍历它,请选择 Box

【讨论】:

  • 这正是我要找的,我假设 Cons(isize) 是指向数据 Arc 的指针,而实际上恰恰相反。是的,我使用 Arc 是因为希望能够从多个线程中读取但没有互斥体,因为我希望它对除实际所有者之外的任何人都不可变。可能只使用 Box 代替,因为它是列表的唯一所有者。谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-11-28
  • 2011-03-01
  • 2021-11-25
  • 2021-12-24
  • 1970-01-01
  • 1970-01-01
  • 2020-12-23
相关资源
最近更新 更多