Совместное использование переменных между двумя структурами - PullRequest
0 голосов
/ 08 мая 2020

Я новичок в Rust и хотел разделить память между переменными. Я получаю сообщение об ошибке относительно ссылок

use std::collections::HashMap;

struct File {
  file_name: String,
  max_value: Vec<f32>,
}

struct FileHolder<'a> {
  file_holder_name: String,
  first_value: HashMap<String, &'a f32>,
  last_value: HashMap<String, &'a f32>,
}

fn get_file() -> File {
  let x = vec![1f32, 2f32, 3f32, 4f32, 5f32];
  let file = File { file_name: String::from("F1"), max_value: x };
  file
}

fn get_files() -> Vec<File> {
  let file1 = get_file();
  let file2 = get_file();
  let file3 = get_file();
  let file4 = get_file();
  let files = vec![file1, file2, file3, file4];
  files
}

fn transfer_to_holder(files: &Vec<File>) -> HashMap<usize, FileHolder> {

  let mut file_holders = HashMap::new();

  for i in 0..3 {
    let mut file_holder = FileHolder {
      file_holder_name: String::from("FH1"),
      first_value: HashMap::new(),
      last_value: HashMap::new()
    };
    file_holders.insert(i,file_holder);
  }

  files.iter().map(|file| {
    file_holders.iter_mut().map(|(sensor_index, file_holder_temp)| {
      file_holder_temp.first_value.insert(file.file_name.to_string(), &file.max_value[0]);
      file_holder_temp.last_value.insert(file.file_name.to_string(), &file.max_value[4]);
    })
  });


//   for file in files {
//     let i = 0;
//     let mut file_holder_temp = file_holders.get_mut(&i).unwrap();
//     file_holder_temp.first_value.insert(file.file_name.to_string(), &file.max_value[0]);
//     file_holder_temp.first_value.insert(file.file_name.to_string(), &file.max_value[4]);
//   }
  file_holders
}

fn main() {
  let files = get_files();
  let file_holder = transfer_to_holder(&files);
}

Обновление: старый код с ошибками:

use std::collections::HashMap;

Struct File {
  file_name: String,
  value: Vec<f32>
}

Struct FileHolder {
  file_holder_name:String,
  first_value: HashMap<String, &f32>,
  last_value: HashMap<String, &f32>
}

fn get_file()->File {
  let x = [1,2,3,4,5];
  let file = File{file_name: String::from("F1"), value: x};
  return file;
}

fn get_files()->Vec<File> {
  let file1 = get_file();
  let file2 = get_file();
  let file3 = get_file();
  let file4 = get_file();
  let files = Vec[file1, file2, file3, file4];
  return files;
}

fn trasfer_to_holder(files: &Vec<File>) -> FileHolder{
  let file_holder = FileHolder {
    file_holder_name: String::from("FH1"),
    first_value: HashMap::new(),
    last_value: HashMap::new()
  }
  for file in Files {
    file_holder.first_value.insert(file.file_name, &file.value[0]);
    file_holder.last_value.insert(file.file_name, &file.value[4]);
  }
  return file_holder;
}

fn main() {
  let files = get_files();
  let file_holder = trasfer_to_holder(&files);
}

Ниже приведена ошибка

cannot borrow `file_holder.first_value` as mutable, as it is behind a `&` reference

В этом примере У меня всего 5 файлов; Однако в моем реальном случае у меня около 150000 файлов. Если я снова сохраню 150000 first_value и 150000 last_value в FileHolder, это будет пустой тратой ресурсов. Следовательно, было бы неплохо, если бы я сослался на первую ссылку на структуру. Я пробовал несколько вещей; Играли с временем жизни, но это трудно понять новичку.

Примечание: файлы и file_holder никогда не будут изменены после создания; Возможно, в коде есть ошибка;

1 Ответ

2 голосов
/ 08 мая 2020

В приведенном вами примере имеется куча недопустимого синтаксиса и по крайней мере дюжина ошибок компиляции. После очистки я смог скомпилировать пример без каких-либо проблем:

use std::collections::HashMap;

struct File {
  file_name: String,
  max_value: Vec<f32>,
}

struct FileHolder<'a> {
  file_holder_name: String,
  first_value: HashMap<String, &'a f32>,
  last_value: HashMap<String, &'a f32>,
}

fn get_file() -> File {
  let x = vec![1f32, 2f32, 3f32, 4f32, 5f32];
  let file = File { file_name: String::from("F1"), max_value: x };
  file
}

fn get_files() -> Vec<File> {
  let file1 = get_file();
  let file2 = get_file();
  let file3 = get_file();
  let file4 = get_file();
  let files = vec![file1, file2, file3, file4];
  files
}

fn transfer_to_holder(files: &[File]) -> FileHolder {
  let mut file_holder = FileHolder {
    file_holder_name: String::from("FH1"),
    first_value: HashMap::new(),
    last_value: HashMap::new()
  };
  for file in files {
    file_holder.first_value.insert(file.file_name.to_string(), &file.max_value[0]);
    file_holder.first_value.insert(file.file_name.to_string(), &file.max_value[4]);
  }
  file_holder
}

fn main() {
  let files = get_files();
  let file_holder = transfer_to_holder(&files);
}

игровая площадка

Кроме того, то, что вы пытаетесь сделать, чтобы «сэкономить место» "на самом деле контрпродуктивно, поскольку во всех системах &f32 такой же, если не вдвое больше, чем f32. На игровой площадке &f32 действительно вдвое больше f32:

fn main() {
  dbg!(std::mem::size_of::<f32>()); // prints "4" bytes
  dbg!(std::mem::size_of::<&f32>()); // prints "8" bytes
}

детская площадка

Таким образом, вы можете одновременно сэкономить место, упростить свой код, избавьтесь от ссылок и аннотаций времени жизни и просто go с помощью этого:

use std::collections::HashMap;

struct File {
  file_name: String,
  max_value: Vec<f32>,
}

struct FileHolder {
  file_holder_name: String,
  first_value: HashMap<String, f32>,
  last_value: HashMap<String, f32>,
}

fn get_file() -> File {
  let x = vec![1f32, 2f32, 3f32, 4f32, 5f32];
  let file = File { file_name: String::from("F1"), max_value: x };
  file
}

fn get_files() -> Vec<File> {
  let file1 = get_file();
  let file2 = get_file();
  let file3 = get_file();
  let file4 = get_file();
  let files = vec![file1, file2, file3, file4];
  files
}

fn transfer_to_holder(files: &[File]) -> FileHolder {
  let mut file_holder = FileHolder {
    file_holder_name: String::from("FH1"),
    first_value: HashMap::new(),
    last_value: HashMap::new()
  };
  for file in files {
    file_holder.first_value.insert(file.file_name.to_string(), file.max_value[0]);
    file_holder.first_value.insert(file.file_name.to_string(), file.max_value[4]);
  }
  file_holder
}

fn main() {
  let files = get_files();
  let file_holder = transfer_to_holder(&files);
}

игровая площадка

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...