【问题标题】:error: use of moved value res in Rust错误:在 Rust 中使用移动值 res
【发布时间】:2014-12-01 08:57:15
【问题描述】:

这段代码是怎么回事:

fn method1(a: &str) -> (String, String) {
  let res = method2(a);
  (res.val0(), res.val1())
}

错误是:

error: use of moved value res

我该如何解决?

【问题讨论】:

    标签: rust


    【解决方案1】:

    看起来method2() 返回一个不可复制的对象,而val0()val1() 方法通过值获取它们的目标:

    struct SomeType { ... }
    
    impl SomeType {
        fn val0(self) -> String { ... }
        fn val1(self) -> String { ... }
    }
    
    fn method2(a: &str) -> SomeType { ... }
    
    fn method1(a: &str) -> (String, String) {
        let res = method2(a);
        (res.val0(), res.val1())
    }
    

    因为SomeType 不是自动可复制的,它将被移动到按值获取它的方法中,但是您尝试这样做两次,这是不合理的,并且编译器报告“使用移动值”错误。

    如果您无法更改SomeType,并且它只有val0()val1() 方法,没有公共字段并且没有实现Clone。那你就不走运了。您将只能获得 val0()val1() 方法的结果,但不能同时获得两者。

    如果SomeType 也有返回引用的方法,像这样:

    impl SomeType {
        fn ref0(&self) -> &String { ... }
        fn ref1(&self) -> &String { ... }
    }
    

    &str 代替 &String 也可以) 然后你可以克隆字符串:

    let res = method2(a);
    (res.ref0().clone(), res.ref1().clone())
    

    如果SomeType 提供某种解构功能就更好了,例如:

    impl SomeType {
        fn into_tuple(self) -> (String, String) { ... }
    }
    

    那么就直截了当:

    method2(a).into_tuple()
    

    如果SomeType本身就是一个二元元组,你甚至不需要into_tuple(),直接写method2()调用即可:

    method2(a)
    

    元组还为元组和元组结构提供tuple indexing syntax,而不是即将被弃用的tuple traits。也可以使用:

    let res = method2(a);
    (res.0, res.1)
    

    如果SomeType 确实是一个相同大小的元组,那是多余的,但如果SomeType 是一个更大的元组,这是要走的路。或者你可以使用解构:

    let (v1, v2, _) = method2(a);  // need as many placeholders as there are remaining elements in the tuple
    (v1, v2)
    

    【讨论】:

    • method2返回一个元组(String, String, .....),从res.val0()res.val1()方法调用可以看出。
    • 我怀疑是这样,但没有人阻止您将自定义 val0()val1() 方法添加到您想要的任何数据类型,@PaoloFalabela 在他的评论中完美地证明了这一点。
    • @VladimirMatveev 我不小心删除了我的评论。 Playpen 链接再次供参考is.gd/3ySXZi(顺便说一句,不知道这些能活多久……)
    • Da chtozh ya sovsem uzhe iz uma vizhil chtobi dobavlyat' metodi s takimi imenami?
    猜你喜欢
    • 1970-01-01
    • 2021-06-01
    • 2013-07-01
    • 1970-01-01
    • 2022-11-27
    • 1970-01-01
    • 1970-01-01
    • 2019-12-05
    • 2017-06-28
    相关资源
    最近更新 更多