如果需要存储一个书籍列表和一个作者列表,其中一本书是由一个作者写的,而一个作者可能写了很多书。如何在 Rust 程序中对其进行编码?
要求如下:
对于任何给定的对象,访问与其相关的对象应该是低复杂度的。
使不可能的状态成为不可能。如果数据冗余,就会出现不连贯。
每个作者和书籍都由一个唯一值(此处为表中的索引)标识。
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] },
];
这种方法满足第一个要求,但不满足第二个要求。具体实现中,可以使用hash map或者
Slab
集合。
struct Book {
author: Weak<Author>,
}
struct Author {
books: Vec<Weak<Book>>,
}
let books = vec![
Rc::new(Book { author: todo!() }),
Rc::new(Book { author: todo!() }),
Rc::new(Book { author: todo!() }),
];
let authors = vec![
Author { books: vec![books[0].clone().downgrade(), books[1].clone().downgrade()] },
Author { books: vec![books[2].clone().downgrade() },
];
这是行不通的,因为存在循环依赖。然而,我知道有一些解决方法,比如内部可变性,但这里的重点是我很难看到如何使用 Rust 类型系统和不同的可用工具来在满足我的两个要求的对象之间建立优雅的关系.
知道上面的例子是一个最小的例子。我的项目涉及玩家拥有的城镇,有移动单位、资源等……
我仍然认为第一种方法是最简单的方法,并且可以通过适当的类型和代码结构安全(几乎满足第二个要求)。
感谢您的帮助!