我有一个书单和一个作者列表,其中一本书是由一个作者写的,而一个作者可能写了很多本书,我该如何在Rust程序中编码呢?
要求:
1.对于任何给定的对象,访问与之相关的对象应该是低复杂度的。
1.应该防止不可能的状态。如果数据是冗余的,则会出现不一致。
一种方法:
每个作者和书都由一个唯一的值标识(这里是表中的索引)。
struct Book {
author: usize,
}
struct Author {
books: Vec<usize>,
}
let books = vec![
Book { author: 0 },
Book { author: 0 },
Book { author: 1 },
];
let authors = vec![
Author { books: vec![0, 1] },
Author { books: vec![2] },
];
这种方法满足了第一个要求,但不满足第二个要求。在一个实现中,可以使用散列Map或Slab
集合来确保id保持有效。
我不知道如何使用Rust类型系统和不同的工具来建立满足我的两个需求的对象之间的关系。
这是编程中经常出现的一种模式,我可能是在重新发明轮子。
1条答案
按热度按时间mqkwyuun1#
我不知道你需要多少帮助也许你会发现下面的例子是微不足道的。
资源(书籍和作者)的所有权完全在图书馆的控制之下。因为场景非常简单(不删除书籍和作者),这些资源之间的关系只依赖于数字索引。如果我们需要删除资源的能力,一些generational indices可以帮助我们;在这种情况下,当访问这些资源时,必须考虑一些可能的故障(
Option
/Result
)。在当前的场景中,所有关于索引的细节都隐藏在公共接口中。因此,我们提供迭代器(
impl Iterator
...)来检查资源。如果索引必须在公共接口中公开,则仍然可以通过迭代器进行随机访问(尽管提供切片可能会更自然)。注意,由于
impl
,迭代器类型在编译步骤中是精确已知的,并且可能会被优化掉,就好像我们直接在主程序中处理带有数字索引的切片一样。