在Rust 0.8中:
struct TwoStr {
one: ~str,
two: ~str,
}
#[test]
fn test_contents() {
let strs = TwoStr {
one: ~"pillar",
two: ~"post",
};
assert_eq!(strs.one, ~"pillar");
assert_eq!(strs.two, ~"post");
}
代码甚至不会编译。 rust test
认为第二个assert_eq
中存在错误:
错误:使用部分移动的值:
strs
这有点违反直觉。我的意思是,无论第一个assert_eq
可能产生什么影响,当执行到达第二个assert_eq
时,它应该远远超出范围。除非当然,它会在场景后面产生一些东西。是吗?
如果没有,为什么会出现这个神秘的错误?希望我对Rust指针的理解没有根本的缺陷。
答案 0 :(得分:6)
在Rust 0.8中,assert_eq!
被定义为
macro_rules! assert_eq (
($given:expr , $expected:expr) => (
{
let given_val = $given;
let expected_val = $expected;
// check both directions of equality....
if !((given_val == expected_val) && (expected_val == given_val)) {
fail!(\"assertion failed: `(left == right) && (right == \
left)` (left: `%?`, right: `%?`)\", given_val, expected_val);
}
}
)
)
请注意,它将两个参数都移动到本地let-bindings given_val
和expected_val
。这就是造成错误的原因。
在当前的主人中,这已得到修复。 assert_eq!
现在引用了参数:
macro_rules! assert_eq (
($given:expr , $expected:expr) => (
{
let given_val = &($given);
let expected_val = &($expected);
// check both directions of equality....
if !((*given_val == *expected_val) &&
(*expected_val == *given_val)) {
fail!("assertion failed: `(left == right) && (right == left)` \
(left: `{:?}`, right: `{:?}`)", *given_val, *expected_val)
}
}
)
)
这意味着它不再移动其参数,从而修复了您的错误。
如果您需要坚持使用生锈0.8,您可以将其更改为使用assert!()
而直接进行比较,这样可以避免移动。但我的建议是升级到最新的主人。
答案 1 :(得分:3)