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()
    工作,这意味着您可以在需要类型的任何地方编写
    Steps
    。(其他两种可能性都有问题:使用struct字段,即
    #[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
}