【发布时间】:2016-04-03 20:32:55
【问题描述】:
Rust quickcheck documentation 指出,对于任何实现 Arbitrary 的类型
它们还必须是可发送的和静态的,因为每个测试都使用 thread::Builder::spawn 在其自己的线程中运行,这需要 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(或任何最终名称)稳定下来,这个限制可能会被解除,但我不确定。 -
啊,好吧,这是非常明确的答案。稳定讨论是here?由于在自己的线程中运行每个测试,因此存在此限制的唯一原因是文档所述吗?如果测试是连续运行的,会取消限制还是会出现后续并发症?
-
另外,感谢您提供的超级有用的测试库! :)
-
@troutwine
impl Arbitrary for C<'statc>不工作吗?在任何情况下,非静态数据的Arbitrary实例都没有多大意义。考虑对g.gen::<&str>()的调用,它不会编译,因为&str没有实现Rand(除了静态字符串之外,&str 还能是什么?)。 -
@Mar 很可能我需要再次访问文档。这是由我的第一个非玩具 Rust 项目推动的。我正在做的是编写 QC 测试来验证解析器,属性是
parse . format应该是身份,稍微抄袭 Haskell 语法。需要生成包含 &str 的任意结构实例。但是,假设这从根本上是有缺陷的,因为它们无论如何都不会是 same 引用。
标签: rust quickcheck