【问题标题】:How can I transfer ownership to a calling function?如何将所有权转移给调用函数?
【发布时间】:2020-03-12 04:03:12
【问题描述】:

我知道必须有一种方法可以将变量的所有权从函数转移到其调用上下文。这是我目前所拥有的:

fn get_transferables(creep: &Creep) -> &Vec<Structure> {
    let targets = creep.room().find(find::STRUCTURES);
    &targets
        .iter()
        .filter(|s| {
            use Structure::*;
            match s {
                Extension(s) => s.store_free_capacity(Some(ResourceType::Energy)) > 0,
                Spawn(s) => s.store_free_capacity(Some(ResourceType::Energy)) > 0,
                Tower(s) => s.store_free_capacity(Some(ResourceType::Energy)) > 0,
                _ => false,
            }
        })
        .collect::<Vec<&Structure>>()
        .iter()
        .map(|&element| Structure::from(*element))
        .collect()
}

当我尝试取消引用元素时出现“无法移出共享引用”错误,并且“无法返回对临时值的引用”。

如果我注释掉这些行:

// .collect::<Vec<&Structure>>()
// .iter()
// .map(|&element| Structure::from(*element))

我得到“无法通过迭代器在 '&Structure' 类型的元素上构建 'Vec' 类型的值”。

当我尝试让函数返回 Vec&lt;Structure&gt; 时,我又遇到了另一个错误。我觉得我在绕圈子跑。我知道使用::new() 构造函数,您只需在创建它后立即传递一个结构,但这变得非常令人沮丧。

【问题讨论】:

  • 很难回答您的问题,因为它不包含minimal reproducible example。我们无法分辨代码中存在哪些 crate(及其版本)、类型、特征、字段等。如果您尝试在Rust Playground 上重现您的错误,如果可能的话,这将使我们更容易为您提供帮助,否则在全新的 Cargo 项目中,然后在edit 您的问题中包含附加信息。您可以使用Rust-specific MRE tips 来减少您在此处发布的原始代码。谢谢!
  • edit 您的问题并粘贴您所得到的准确和完整的错误——这将帮助我们了解问题所在,以便我们能够提供最好的帮助。有时试图解释错误消息很棘手,实际上错误消息的不同部分很重要。请使用直接运行编译器的消息,而不是 IDE 生成的消息,它可能会尝试为您解释错误。
  • Cannot move out of borrowed content when trying to transfer ownership的答案可能会回答您的问题。如果没有,请edit您的问题来解释差异。否则,我们可以将此问题标记为已回答。

标签: rust screeps


【解决方案1】:

我不得不将它分解为两个独立的函数,并让我的调用代码来回传递引用,这样就形成了无缝的监管链(就像犯罪现场的证据一样)。这就是我最终得到的结果:

在我的主要功能中:

let structures = get_structures(&self);
let transferables = get_transferables(&structures);

我的新功能:

fn get_structures(creep: &Creep) -> Vec<Structure> {
    creep.room().find(find::STRUCTURES)
}

fn get_transferables<'a>(targets: &'a Vec<Structure>) -> Vec<&'a Structure> {
    targets
        .iter()
        .filter(|s| {
            use Structure::*;
            match s {
                Extension(s) => s.store_free_capacity(Some(ResourceType::Energy)) > 0,
                Spawn(s) => s.store_free_capacity(Some(ResourceType::Energy)) > 0,
                Tower(s) => s.store_free_capacity(Some(ResourceType::Energy)) > 0,
                _ => false,
            }
        })
        // .collect::<Vec<&Structure>>()
        // .iter()
        // .map(|&element| Structure::from(*element))
        .collect()
}

我仍然认为应该有更好的解决方案。

【讨论】:

    猜你喜欢
    • 2015-01-23
    • 2014-07-21
    • 1970-01-01
    • 2015-05-21
    • 1970-01-01
    • 2014-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多