在 2 个结构之间共享变量

Share variables between 2 structs

我是 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 个文件。如果我在 FileHolder 中再次存储 150000 first_value 和 150000 last_value,这是资源浪费。因此,如果我引用第一个结构的引用就好了。我试过很多东西;玩了一辈子,新手看不懂。

注意:文件和file_holder一旦创建就永远不会改变;代码中可能有一些错误。

您提供的示例中存在大量无效语法和至少十几个编译错误。清理后,我能够毫无问题地编译示例:

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

playground

此外,你试图对 "save space" 做的事情实际上适得其反,因为在所有系统上,&f32 与 [=14= 一样大,如果不是两倍的话。 ].在 playground 环境中,&f32 确实是 f32:

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

playground

因此,您可以同时节省 space,简化您的代码,摆脱引用和生命周期注释,然后就这样:

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

playground