Rust 在库模块及其测试模块之间共享数据
我有一个寻路算法库和一个测试模块,它以图形方式显示算法所采取的每一步。其思想是,应该能够有条件地编译算法测试或库。因此,算法对象应该保持精简,不存储或返回任何在测试之外不需要的数据 目前,我使用一个文本文件作为中间存储,在任何时候都将这些步骤写入其中。搜索完成后,测试模块从那里读取它们 测试模块是算法模块的子模块Rust 在库模块及其测试模块之间共享数据,rust,conditional-compilation,Rust,Conditional Compilation,我有一个寻路算法库和一个测试模块,它以图形方式显示算法所采取的每一步。其思想是,应该能够有条件地编译算法测试或库。因此,算法对象应该保持精简,不存储或返回任何在测试之外不需要的数据 目前,我使用一个文本文件作为中间存储,在任何时候都将这些步骤写入其中。搜索完成后,测试模块从那里读取它们 测试模块是算法模块的子模块 是否有更好的中间存储?有没有办法得到一个静态可变向量?我也读了一些关于任务本地存储的内容,但没有很好的文档记录 编辑: 不幸的是,这样的事情似乎不起作用: pub struct Jum
是否有更好的中间存储?有没有办法得到一个静态可变向量?我也读了一些关于任务本地存储的内容,但没有很好的文档记录 编辑: 不幸的是,这样的事情似乎不起作用:
pub struct JumpPointSearch {
closed_set: Vec<Node>,
open_set: PriorityQueue<Node>,
#[cfg(demo)] steps: Vec<(Point2<uint>,Point2<uint>)>
}
impl JumpPointSearch {
pub fn new() -> JumpPointSearch {
if cfg!(demo) {
JumpPointSearch {
closed_set: Vec::with_capacity(40),
open_set: PriorityQueue::with_capacity(10),
steps: Vec::new()
}
} else {
JumpPointSearch { // error: missing field: `steps`
closed_set: Vec::with_capacity(40),
open_set: PriorityQueue::with_capacity(10),
}
}
}
}
pub-struct-JumpPointSearch{
闭集:Vec,
打开集合:优先级队列,
#[cfg(演示)]步骤:Vec
}
impl跳转点搜索{
pub fn new()->JumpPointSearch{
如果是cfg!(演示){
跳点搜索{
闭合的_集:Vec::具有_容量(40),
open_set:PriorityQueue::具有_容量(10),
步骤:Vec::new()
}
}否则{
JumpPointSearch{//错误:缺少字段:`steps`
闭合的_集:Vec::具有_容量(40),
open_set:PriorityQueue::具有_容量(10),
}
}
}
}
这也不起作用:
pub struct JumpPointSearch {
closed_set: Vec<Node>,
open_set: PriorityQueue<Node>,
#[cfg(demo)] steps: Vec<(Point2<uint>,Point2<uint>)>
}
impl JumpPointSearch {
pub fn new() -> JumpPointSearch {
JumpPointSearch {
closed_set: Vec::with_capacity(40),
open_set: PriorityQueue::with_capacity(10),
#[cfg(demo)] steps: Vec::new()
// error: expected ident, found `#`
}
}
}
pub-struct-JumpPointSearch{
闭集:Vec,
打开集合:优先级队列,
#[cfg(演示)]步骤:Vec
}
impl跳转点搜索{
pub fn new()->JumpPointSearch{
跳点搜索{
闭合的_集:Vec::具有_容量(40),
open_set:PriorityQueue::具有_容量(10),
#[cfg(demo)]步骤:Vec::new()
//错误:应为标识符,但未找到`#`
}
}
}
对于这样的条件定义,您需要使用属性表单,而不是宏。就是
#[cfg(demo)]
pub fn new() -> JumpPointSearch {
JumpPointSearch {
closed_set: Vec::with_capacity(40),
open_set: PriorityQueue::with_capacity(10),
steps: Vec::new()
}
}
#[cfg(not(demo))]
pub fn new() -> JumpPointSearch {
JumpPointSearch {
closed_set: Vec::with_capacity(40),
open_set: PriorityQueue::with_capacity(10),
}
}
cfg
宏只会根据配置是否匹配而扩展为true
或false
,也就是说,两个分支都没有被消除,并且类型检查(等等)仍然会同时发生,这就是它不起作用的原因:其中一个结构初始化与定义不匹配
然而,我认为这有更高层次的方法,它们都非常相似,但要点是让
JumpPointSearch
实现始终相同,只需更改步骤
字段
真正的泛型
如果您不需要扩展性,并且很乐意在编译时进行固定选择,那么我建议您使用这种方法:您根本不需要太多的#[cfg]
s(只需要上面两个,可能还有两个,这取决于您如何处理从步骤
字段提取数据)你不必到处乱扔泛型
两点:
- 像这样使用
允许use
工作,这意味着您可以在需要类型的任何地方编写Steps::new()
。(其他两种可能性都有问题:使用struct字段,即Steps
,两者都失败;使用#[cfg(demo)]步骤:DebugSteps
还不允许#[cfg(demo)]类型steps=DebugSteps;
)步骤::new()
- 您还可以删除此方法的
特性,直接步骤
方法,即:impl
和类似的impl ReleaseSteps{fn new()->ReleaseSteps{…}fn register\u Steps(…){}
DebugSteps
#[cfg(test)]
)以便在不需要时编译出来吗?@delnan我尝试过这个方法,但没有成功。请参阅我的编辑。“我也读了一些关于任务本地存储的内容,但没有很好的文档记录。”你的意思是?(编译需要将#[cfg]
放在新的函数上。)
struct ReleaseSteps;
struct DebugSteps {
steps: Vec<(Point2<uint>, Point2<uint>)>
}
trait Step {
fn register_step(&mut self, step: (Point<uint>, Point<uint>));
}
impl Step for ReleaseSteps {
#[inline(always)] // ensure that this is always 0 overhead
fn register_step(&mut self, step: (Point<uint>, Point<uint>)) {}
}
impl Step for DebugSteps {
fn register_step(&mut self, step: (Point<uint>, Point<uint>)) {
self.steps.push(step)
}
}
struct JumpPointSearch<St> {
closed_set: Vec<Node>,
open_set: PriorityQueue<Node>,
steps: St
}
impl<St: Step> JumpPointSearch<St> {
fn new(step: St) -> JumpPointSearch<St> { ... }
}
#[cfg(demo)]
use Steps = DebugSteps;
#[cfg(not(demo))]
use Steps = ReleaseSteps;
struct JumpPointSearch {
closed_set: Vec<Node>,
open_set: PriorityQueue<Node>,
steps: Steps
}