Rust“错误:移出不可变的字段”

时间:2013-06-03 20:09:20

标签: immutability rust

我创建了以下Rust结构:

struct HTTPRequestHeader {
    name: ~str,
    data: ~str,
    next: Option<~HTTPRequestHeader>
}

以下代码打印出来:

fn print_headers(hdr: &HTTPRequestHeader) {
    println(fmt!("%s: %s", (*hdr).name, (*hdr).data));
    match (*hdr).next {
        Some(next_hdr) => { print_headers(next_hdr); }
        None => { }
    }
}

尝试编译此代码,我收到以下错误:

> rustc http_parse.rs
http_parse.rs:37:7: 37:18 error: moving out of immutable field
http_parse.rs:37    match (*hdr).next {
                          ^~~~~~~~~~~
error: aborting due to previous error

这是什么意思?包含(*hdr).name, (*hdr).data)的行无错误地编译。 match语句不应该试图以任何方式改变hdr.next,所以我不知道它是如何变异的。我试图编写一个不带指针的修改版本:

fn print_headers(hdr: HTTPRequestHeader) {
    println(fmt!("%s: %s", hdr.name, hdr.data));
    match hdr.next {
        Some(next_hdr) => { print_headers(*next_hdr); }
        None => { }
    }
}

这个给了我:

> rustc http_parse.rs
http_parse.rs:37:7: 37:15 error: moving out of immutable field
http_parse.rs:37    match hdr.next {
                          ^~~~~~~~
http_parse.rs:38:36: 38:45 error: moving out of dereference of immutable ~ pointer
http_parse.rs:38        Some(next_hdr) => { print_headers(*next_hdr); }
                                                          ^~~~~~~~~
error: aborting due to 2 previous errors

请帮助我了解这里发生了什么! :)

1 个答案:

答案 0 :(得分:7)

虽然错误确实告诉您从移动值的位置,但它并不表示您尝试将其移动到的位置,这可能有所帮助让它更清楚为什么它不起作用。

问题是您有一个唯一的指针(Option<~HTTPRequestHeader>),这意味着您需要对其进行引用或制作副本。由于它们只能拥有一个所有者,因此默认情况下会移动它们。这是您比赛的Some(next_hdr)分支中发生的事情。

所以你可能想要的是这样的:

fn print_headers(hdr: &HTTPRequestHeader) {
    println(fmt!("%s: %s", hdr.name, hdr.data));
    match hdr.next {
        Some(ref next_hdr) => print_headers(*next_hdr),
        None => {}
    }
}

另外,附注:如果您想通过指针访问某个结构的字段,则不需要明确地取消引用它(即只有hdr.name(*hdr).name一样有效。