Rust 关于不能一次多次借用'x'作为可变项的另一个询问错误

Rust 关于不能一次多次借用'x'作为可变项的另一个询问错误,rust,Rust,考虑到以下准则: struct Foo { x: i32, } struct Test { foos: Vec<Foo>, v: i32, } fn bar(test: &mut Test, foo: &mut Foo){ // make something with test foo.x = 42; } fn main() { let test = &mut Test { foos: ve

考虑到以下准则:

struct Foo {
    x: i32,
}

struct Test {
    foos: Vec<Foo>,
    v: i32,
}

fn bar(test: &mut Test, foo: &mut Foo){
    // make something with test
    foo.x = 42;
}

fn main() {
    let test = &mut Test {
        foos: vec![
            Foo {x: 3}, 
            Foo {x: 4},
        ], 
        v: 55
    };

    // First time test got borrowed
    let iterator = test.foos.iter_mut();

    for elem in iterator {
        // !!Error second time test got borrowed as mutable
        bar(test, elem);
    }

}

但是,根据结构的不同,克隆结构可能会让人觉得代价高昂。

您链接到的GitHub Java示例实际上并不要求父级和子级都是可变的。事实上,父级(在Java中,这是
safebox
)只调用
getUploadUrl()

因此,我将它稍微翻译为Rust,并使用与Java示例类似的类型名。这个想法是方法本身只关心URL。。。因此,直接传递它,而不是采用可变引用:

struct Attachment {
    guid: String,
}

impl Attachment {
    fn new<S>(guid: S) -> Attachment
        where S: Into<String>
    {
        Attachment { guid: guid.into() }
    }

    fn set_guid<S>(&mut self, guid: S)
        where S: Into<String>
    {
        self.guid = guid.into();
    }
}

struct SafeBox {
    attachments: Vec<Attachment>,
    upload_url: &'static str,
}

impl SafeBox {
    fn get_upload_url(&self) -> &str {
        self.upload_url
    }
}

fn uploadAttachment(upload_url: &str, attachment: &mut Attachment) {
    attachment.set_guid("12345");
}

fn main() {
    let mut safebox = SafeBox {
        attachments: vec![Attachment::new("12345"), Attachment::new("67890")],
        upload_url: "http://upload.com/upload",
    };

    for mut attachment in &mut safebox.attachments {
        uploadAttachment(safebox.upload_url, &mut attachment);
    }
}
struct附件{
guid:字符串,
}
植入附件{
fn新(guid:S)->附件
S:去哪里
{
附件{guid:guid.into()}
}
fn set_guid(&mut self,guid:S)
S:去哪里
{
self.guid=guid.into();
}
}
结构保险箱{
附件:Vec


作为一个曾经尝试过将一个简单的C#库移植到Rust的人,我可以从经验中告诉你,尝试以行为行,以类型为类型移植它是一个坏主意无法直接进行移植。

我可以问一下为什么不能更改函数签名吗?在我看来,这似乎是在关闭潜在解决方案的大门,并创建了一个新的解决方案。我理解您的示例仅限于基本内容,但在不了解更多内容的情况下,同时要求子对象及其子对象的可变性似乎很奇怪父函数在同一个函数签名中(在这个特定的小示例中)。也许您可以传递父函数或仅传递子函数,调用方可以对其执行操作的
结果
?为了防止生锈,我决定重写一个设计已经确定的库()我想保持与其他语言相同的同质性。我正在做一些与Java类似的事情。这里,
uploadAttachment()
是我在上面的示例中编写的
bar()
函数。如果我可以大胆地说一句(快速查看了链接到的Java示例)-您的实际用例并不要求父级是可变的。
uploadAttachment
在您链接的GitHub源代码中,只有在
safebox
上调用
getUploadUrl
。我想说,将其转换为Rust应该是直接的,因为您可以单独传递URL,而无需加倍可变引用。是的,我理解尝试一行一行地移植代码是一个坏主意。但是由于“盒子内部”不同,我的目标是尝试为同源性提供相同的API。为什么
uploadAttachment()
的签名保持原样,是因为
submitSafebox(&mut-safebox)
因为[call to]()
初始化safebox(&mut-safebox)
而需要可变借阅。但是你是对的,给
上传附件
url可能是最正常的做法。
struct Attachment {
    guid: String,
}

impl Attachment {
    fn new<S>(guid: S) -> Attachment
        where S: Into<String>
    {
        Attachment { guid: guid.into() }
    }

    fn set_guid<S>(&mut self, guid: S)
        where S: Into<String>
    {
        self.guid = guid.into();
    }
}

struct SafeBox {
    attachments: Vec<Attachment>,
    upload_url: &'static str,
}

impl SafeBox {
    fn get_upload_url(&self) -> &str {
        self.upload_url
    }
}

fn uploadAttachment(upload_url: &str, attachment: &mut Attachment) {
    attachment.set_guid("12345");
}

fn main() {
    let mut safebox = SafeBox {
        attachments: vec![Attachment::new("12345"), Attachment::new("67890")],
        upload_url: "http://upload.com/upload",
    };

    for mut attachment in &mut safebox.attachments {
        uploadAttachment(safebox.upload_url, &mut attachment);
    }
}