rust - 使用 HashMap 解决借用问题(2020 年代码出现的剧透)
问题描述
第一次发布海报,对 Rust 非常陌生。在过去的几个月里,我一直在慢慢地玩 Rust,而我最近才努力学习这门语言。为了帮助我解决这个问题,我计划解决今年Rust代码出现的所有问题。目前我被困在第四天。如果你想在这里阅读它是链接。显然,我可能会为你们中的一些人破坏这个问题,所以请注意!无论如何要解决问题!
对于这个问题,我决定使用 HashMap 来解决第一部分。我来自 Java 和 Python,所以我认为 Rust 的 HashMap 的工作方式类似于 Java 和 Python 的字典。我意识到这可能不是最好的解决方案,但我还是想尝试一下以了解 HashMaps。这是我想出的代码。我试图注释代码以便更容易理解。
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::collections::HashMap;
fn check_passport_valid(passport: HashMap<&str, &str>) -> bool {
return true;
}
fn main() {
// set up a bufReader to read the data
let data = "data/data.txt";
let file = File::open(data).unwrap();
let reader = BufReader::new(file);
// init a mutable HashMap
let mut passport: HashMap<&str, &str> = HashMap::new();
let mut count = 0;
// read the data in line by line
for line in reader.lines() {
// not sure if i should &line.unwrap() or do this
// seems to work the same in both situations
let s = line.unwrap();
// if line is blank check password and init new HashMap
if "" == s {
if check_passport_valid(passport) { count += 1; }
passport = HashMap::new();
}
// else put values into HashMap
else {
// first split into items
let items: Vec<&str> = s.split(' ').collect();
for item in items {
// split into key/value pair
let pair: Vec<&str> = item.split(':').collect();
passport.insert(pair[0], pair[1]);
}
}
}
println!("{}", count);
}
如您所见,它没有完成,但是我收到以下错误:
error[E0597]: `s` does not live long enough
--> src/main.rs:34:36
|
27 | if check_passport_valid(passport) { count += 1; }
| -------- borrow later used here
...
34 | let items: Vec<&str> = s.split(' ').collect();
| ^ borrowed value does not live long enough
...
41 | }
| - `s` dropped here while still borrowed
我尝试过借用不同的值,但我似乎无法让它发挥作用。任何帮助将不胜感激!
解决方案
你得到的错误是你得到的值s.split(' ')
是变量的切片lines
,这基本上意味着它们引用了lines
变量。在循环结束时,该lines
变量被删除并由下一行替换,这会使对其的所有引用无效。最简单的方法是将 转换&str
为String
(拥有的类型) with .to_owned()
,因此它将数据复制到不再依赖于lines
变量的静态内存位置:
use std::fs::File;
use std::io::{BufRead, BufReader};
use std::collections::HashMap;
// this is now HashMap<String, String> instead of HashMap<&str, &str>
fn check_passport_valid(passport: HashMap<String, String>) -> bool {
return true;
}
fn main() {
let data = "data/data.txt";
let file = File::open(data).unwrap();
let reader = BufReader::new(file);
// this is now HashMap<String, String> instead of HashMap<&str, &str>
let mut passport: HashMap<String, String> = HashMap::new();
let mut count = 0;
for line in reader.lines() {
let s = line.unwrap();
if "" == s {
if check_passport_valid(passport) { count += 1; }
passport = HashMap::new();
}
else {
let items: Vec<&str> = s.split(' ').collect();
for item in items {
let pair: Vec<&str> = item.split(':').collect();
// call to_owned on both elements
passport.insert(pair[0].to_owned(), pair[1].to_owned());
}
}
}
println!("{}", count);
}
在此处阅读有关str
vs的更多信息。String
推荐阅读
- rpy2 - 打印 AIC 结果缺少信息
- apache-kafka - Kafka Broker 为生成快速压缩消息的客户端引发错误
- angular - 在 Angular-8 中添加离线导出图表功能
- asp.net-core - 415 未记录的错误:在 [frombody] 中使用 multipart/formdata 的 asp.net 核心 web api 中不受支持的媒体类型
- java - Java POJO 到 OpenApi 的定义
- powershell - powershell:命令列表在 CLI 中运行正常,但在脚本中运行不正常?
- azure-service-fabric - 设置 PartitionCount = NumberOfNodesIntheCluster
- algorithm - 在一维(在一条线上)散布/整理点的算法
- swift - 在 Alamofire 发布请求中发送一个整数(因为它是一个有效的 JSON 对象)
- r - 如果矩阵值小于 0,则乘以