我有一个值,我想在我自己的类型中存储该值以及对该值内部内容的引用:
struct Thing {
count: u32,
}
struct Combined<'a>(Thing, &'a u32);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing { count: 42 };
Combined(thing, &thing.count)
}
Run Code Online (Sandbox Code Playgroud)
有时候,我有一个值,我想在同一个结构中存储该值和对该值的引用:
struct Combined<'a>(Thing, &'a Thing);
fn make_combined<'a>() -> Combined<'a> {
let thing = Thing::new();
Combined(thing, &thing)
}
Run Code Online (Sandbox Code Playgroud)
有时,我甚至没有参考该值,我得到同样的错误:
struct Combined<'a>(Parent, Child<'a>);
fn make_combined<'a>() -> Combined<'a> {
let parent = Parent::new();
let child = parent.child();
Combined(parent, child)
}
Run Code Online (Sandbox Code Playgroud)
在每种情况下,我都会收到一个错误,即其中一个值"活不够长".这个错误是什么意思?
我不明白这个错误cannot move out of borrowed content.我收到了很多次,我总是解决它,但我从来没有理解为什么.
例如:
for line in self.xslg_file.iter() {
self.buffer.clear();
for current_char in line.into_bytes().iter() {
self.buffer.push(*current_char as char);
}
println!("{}", line);
}
Run Code Online (Sandbox Code Playgroud)
产生错误:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)
我通过克隆解决了这个问题line:
error[E0507]: cannot move out of `*line` which is behind a shared reference
--> src/main.rs:31:33
|
31 | for current_char in line.into_bytes().iter() {
| ^^^^ …Run Code Online (Sandbox Code Playgroud) 首先,我尝试了这样的事情:
let mut vec = vec![0];
vec.rotate_right(vec.len());
Run Code Online (Sandbox Code Playgroud)
无法编译,因为:
错误[E0502]:无法借用“vec”作为不可变的,因为它也被借用为可变的
我认为 Rust 借用检查器可能比这更聪明,所以我找到了一个叫做NLL的东西,它应该可以解决这个问题。
我尝试了示例:
let mut vec = vec![0];
vec.resize(vec.len(), 0);
Run Code Online (Sandbox Code Playgroud)
它可以工作,但为什么它不能与 一起工作rotate_right?他们俩都采取了&mut self. 这是怎么回事?
我在Rust中编写了一些连接到远程服务器的代码,根据该服务器发送的消息,计算一些统计信息或根据这些统计信息执行操作.但这对我来说更像是一个学习项目,而且我遇到了一个问题.
这是我已经减少到最低限度以重现问题的代码:
// Repro code for error[E0502]: cannot borrow `*self` as mutable because `self.server` is also borrowed as immutable
use std::collections::HashMap;
struct ServerReader {
server: Vec<u32>, // A vec for demo purposes, but please imagine this is a server object
counters: HashMap<u32, usize>,
}
impl ServerReader {
fn new() -> ServerReader {
ServerReader {
server: vec!(1, 2, 5, 2, 7, 9, 1, 1, 5, 6), // Filling my "server" with some messages
counters: HashMap::new(),
}
}
fn run(&mut self) { …Run Code Online (Sandbox Code Playgroud) 这里发生了什么(游乐场)?
struct Number {
num: i32
}
impl Number {
fn set(&mut self, new_num: i32) {
self.num = new_num;
}
fn get(&self) -> i32 {
self.num
}
}
fn main() {
let mut n = Number{ num: 0 };
n.set(n.get() + 1);
}
Run Code Online (Sandbox Code Playgroud)
给出了这个错误:
error[E0502]: cannot borrow `n` as immutable because it is also borrowed as mutable
--> <anon>:17:11
|
17 | n.set(n.get() + 1);
| - ^ - mutable borrow ends here
| | |
| | …Run Code Online (Sandbox Code Playgroud) use std::fs::File;
use std::io::Read;
pub struct Foo {
maybe_file: Option<File>,
}
impl Foo {
pub fn init(&mut self) {
self.maybe_file = Some(File::open("/proc/uptime").unwrap());
}
pub fn print(&mut self) {
let mut file = self.maybe_file.unwrap();
let mut s = String::new();
file.read_to_string(&mut s).unwrap();
println!("Uptime: {}", s);
}
}
fn main() {}
Run Code Online (Sandbox Code Playgroud)
编译这将给我:
error[E0507]: cannot move out of borrowed content
--> src/main.rs:14:24
|
14 | let mut file = self.maybe_file.unwrap();
| ^^^^ cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)
为什么会这样?我该怎么做才能解决它?
为什么这段代码会编译?
fn get_iter() -> impl Iterator<Item = i32> {
[1, 2, 3].iter().map(|&i| i)
}
fn main() {
let _it = get_iter();
}
Run Code Online (Sandbox Code Playgroud)
[1, 2, 3]是一个局部变量并iter()借用它.此代码不应编译,因为返回的值包含对局部变量的引用.
我正在尝试编写一些玩具代码,用于存储它在一个单词中看到单词的次数HashMap.如果密钥存在,则将计数器递增1,如果密钥不存在,则将其与值相加1.我本能地希望用模式匹配来做这个,但是我不止一次地尝试了一个可变的错误:
fn read_file(name: &str) -> io::Result<HashMap<String, i32>> {
let b = BufReader::new(File::open(name)?);
let mut c = HashMap::new();
for line in b.lines() {
let line = line?;
for word in line.split(" ") {
match c.get_mut(word) {
Some(i) => {
*i += 1;
},
None => {
c.insert(word.to_string(), 1);
}
}
}
}
Ok(c)
}
Run Code Online (Sandbox Code Playgroud)
我得到的错误是:
error[E0499]: cannot borrow `c` as mutable more than once at a time
--> <anon>:21:21
|
16 | match c.get_mut(word) {
| - …Run Code Online (Sandbox Code Playgroud) 我有一个持久的编译错误,其中Rust抱怨我在尝试可变借用时有一个不可变的借位,但是不可变借用来自另一个范围,而我并没有从中带来任何东西.
我有一些代码检查地图中的值,如果它存在,则返回它,否则它需要以各种方式改变地图.问题是我似乎无法找到让Rust同时执行的方法,即使这两个操作完全分开.
这是一些荒谬的代码,它遵循与我的代码相同的结构并展示了问题:
use std::collections::BTreeMap;
fn do_stuff(map: &mut BTreeMap<i32, i32>, key: i32) -> Option<&i32> {
// extra scope in vain attempt to contain the borrow
{
// borrow immutably
if let Some(key) = map.get(&key) {
return Some(key);
}
}
// now I'm DONE with the immutable borrow, but rustc still thinks it's borrowed
map.insert(0, 0); // borrow mutably, which errors
None
}
Run Code Online (Sandbox Code Playgroud)
这出错了:
error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable
--> src/lib.rs:14:5
|
3 …Run Code Online (Sandbox Code Playgroud) 在这种情况下,错误意味着什么:
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3, 4, 5];
v[v[1]] = 999;
}
Run Code Online (Sandbox Code Playgroud)
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3, 4, 5];
v[v[1]] = 999;
}
Run Code Online (Sandbox Code Playgroud)
我发现索引是通过Index和IndexMut特性实现的,这v[1]是*v.index(1). 有了这些知识,我尝试运行以下代码:
use std::ops::{Index, IndexMut};
fn main() {
let mut v: Vec<usize> = vec![1, 2, 3, 4, 5];
*v.index_mut(*v.index(1)) = 999;
}
Run Code Online (Sandbox Code Playgroud)
令我惊讶的是,这完美无缺!为什么第一个片段不起作用,但第二个片段起作用?我理解文档的方式,它们应该是等效的,但显然情况并非如此。