Rust:使用部分移动的值

标签 rust

在 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 有错误:

error: use of partially moved value: strs

这有点违反直觉。我的意思是,无论第一个 assert_eq 可能产生什么影响,当执行到第二个 assert_eq 时,它应该完全超出范围。当然,除非它确实在幕后产生了一些。是吗?

如果不是,为什么会出现这个神秘的错误?希望我对 Rust 指针的理解没有根本性的缺陷。

最佳答案

在 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_valexpected_val 中。这就是导致错误的原因。

在当前的 master 中,这已得到修复。 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)
            }
        }
    )
)

这意味着它不再移动其参数,从而修复了您的错误。

如果你需要坚持使用 rust 0.8,你可以改为使用 assert!() 并直接进行比较,这样可以避免移动。但我的建议是升级到最新的 master。

关于Rust:使用部分移动的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20543746/

相关文章:

casting - `as` 允许进行哪些转换?

rust - 如何将 future::join_all() 转换为使用 FuturesUnordered?

rust - 使用Rc <RefCell <.. >>实现二进制搜索树时的生命周期问题

iterator - 在不创建临时向量的情况下迭代成对的 block

path - 给定两个绝对路径,我该如何表达相对于另一个的路径?

rust - 如何将不同的类实例分配给 Rust 中的变量?

rust - 如果我的应用程序崩溃,我如何确保派生的子进程被终止?

iterator - 为什么在具有推断 Item 类型的 Iter 上调用 cloned() 允许将其传递到此函数中?

rust - 使用 Pest.rs,如何在关键字后允许不重要的空格?

rust - 如何从特征对象中获取对具体类型的引用?