Rust的quickcheck文档指出,任何实现Arbitrary
的类型都必须是可发送和静态的,因为每个测试都在自己的线程中运行,使用thread::Builder::spawn,这需要Send + 'static约束。
由于需要满足Send + 'static约束,因此如果我需要为包含引用的结构体生成数据,该怎么做呢?例如:
#![cfg_attr(test, feature(plugin))]
#![cfg_attr(test, plugin(quickcheck_macros))]
#[cfg(test)]
extern crate quickcheck;
#[cfg(test)]
use quickcheck::{Arbitrary,Gen};
#[allow(dead_code)]
#[derive(Debug,Clone)]
pub struct C<'a> {
s: &'a str,
b: bool
}
#[cfg(test)]
impl<'a> Arbitrary for C<'a> {
fn arbitrary<G: Gen>(g: &mut G) -> C<'a> {
let s = g.gen::<&str>();
C{s: s, b: (s.len() > 0)}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[quickcheck]
fn len_checks_out(c: C) -> bool {
(c.s.len() > 0) == c.b
}
}
失败原因:
cargo test
Compiling qcq v0.1.0 (file:///Users/blt/projects/us/troutwine/qcquestion)
src/lib.rs:18:10: 18:19 error: the type `C<'a>` does not fulfill the required lifetime [E0477]
src/lib.rs:18 impl<'a> Arbitrary for C<'a> {
^~~~~~~~~
note: type must outlive the static lifetime
error: aborting due to previous error
Build failed, waiting for other jobs to finish...
error: Could not compile `qcq`.
这是一个有点牵强的例子,但它与原始问题的精神相同。生命周期注释已经解决了除了测试之外的所有问题。
'static
绑定意味着Arbitrary
的实现不能包含借用数据。一旦panic::recover
(或最终确定的名称)稳定下来,可能会放宽此限制,但我不确定。 - BurntSushi5impl Arbitrary for C<'statc>
有效吗?无论如何,对于非静态数据的Arbitrary
实例都没有太多意义。请考虑调用g.gen::<&str>()
,由于没有&str
的Rand
实现(除了静态字符串之外,它可能是什么?),因此不会编译。 - Marparse . format
应该是恒等式,有点借鉴 Haskell 语法。需要生成包含 &str 的任意结构实例。虽然它们不会是相同的引用,但假设这基本上是有缺陷的。 - troutwine