0

I know there has to be a way to transfer ownership of a variable out of a function to its calling context. This is what I have so far:

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()
}

I get "cannot move out of a shared reference" error when I try to dereference the element, and a "cannot return reference to temporary value".

If I comment out these lines:

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

I get "a value of type 'Vec' cannot be built from an iterator over elements of type '&Structure'".

When I try to have the function return a Vec<Structure> I get yet another error. I feel like I'm running in circles. I know with the ::new() constructor functions you just pass a struct immediately after you create it, but this is getting quite frustrating.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jim Hessin
  • 137
  • 2
  • 11
  • 1
    It's hard to answer your question because it doesn't include a [MRE]. We can't tell what crates (and their versions), types, traits, fields, etc. are present in the code. It would make it easier for us to help you if you try to reproduce your error on the [Rust Playground](https://play.rust-lang.org) if possible, otherwise in a brand new Cargo project, then [edit] your question to include the additional info. There are [Rust-specific MRE tips](//stackoverflow.com/tags/rust/info) you can use to reduce your original code for posting here. Thanks! – Shepmaster Mar 11 '20 at 20:02
  • Please [edit] your question and paste the exact and entire error that you're getting — that will help us to understand what the problem is so we can help best. Sometimes trying to interpret an error message is tricky and it's actually a different part of the error message that's important. Please use the message from running the compiler directly, not the message produced by an IDE, which might be trying to interpret the error for you. – Shepmaster Mar 11 '20 at 20:02
  • Your question might be answered by the answers of [Cannot move out of borrowed content when trying to transfer ownership](https://stackoverflow.com/q/28258548/155423). If not, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster Mar 11 '20 at 20:03

1 Answers1

1

I had to break it into two separate functions and have my calling code pass references back and forth so there is a seamless chain of custody (like evidence at a crime scene). This is what I ended up with:

Inside my main function:

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

My new functions:

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()
}

I still think there should be a better solution.

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Jim Hessin
  • 137
  • 2
  • 11