标签: borrowing

不能将`*x`借用为可变因为它也被借用为不可变的

我正在制作一个组合优化项目来学习Rust,我遇到了一个问题,我无法解决自己...

我有两个功能:

pub fn get_pareto_front_offline<'a>(scheduling_jobs: &'a Vec<Vec<u32>>, costs_vector: &'a Vec<(u32, u32)>) -> Vec<(&'a Vec<u32>, &'a (u32, u32))> {
    // ...
}
Run Code Online (Sandbox Code Playgroud)

pub fn pareto_approach_offline<'a>(list_of_jobs: &'a mut Vec<Vec<u32>>, neighborhood: &'a mut Vec<Vec<u32>>, costs: &'a Vec<(u32, u32)>) -> Vec<(&'a Vec<u32>, &'a (u32, u32))> {
    let pareto_front = get_pareto_front_offline(neighborhood, costs);

    loop {
        if pareto_front == vec![] {
            break;
        }

        neighborhood.clear();

        for front in pareto_front.iter() {
            neighborhood.push((front.0).clone());
        }
    }

    pareto_front
}
Run Code Online (Sandbox Code Playgroud)

我有一个问题,因为编译器告诉我:

cannot borrow '*neighborhood' as mutable because it is also borrowed as …
Run Code Online (Sandbox Code Playgroud)

mutable immutability rust borrowing

2
推荐指数
2
解决办法
1636
查看次数

关于Rust HashMap和String借用的困惑

该程序接受整数N,后跟N行,包含由空格分隔的两个字符串.我想将这些行放入HashMap使用第一个字符串作为键,第二个字符串作为值:

use std::collections::HashMap;
use std::io;

fn main() {
    let mut input = String::new();
    io::stdin().read_line(&mut input)
        .expect("unable to read line");
    let desc_num: u32 = match input.trim().parse() {
        Ok(num) => num,
        Err(_) => panic!("unable to parse")
    };

    let mut map = HashMap::<&str, &str>::new();
    for _ in 0..desc_num {
        input.clear();
        io::stdin().read_line(&mut input)
            .expect("unable to read line");
        let data = input.split_whitespace().collect::<Vec<&str>>();
        println!("{:?}", data);
        // map.insert(data[0], data[1]);
    }
}
Run Code Online (Sandbox Code Playgroud)

该计划按预期工作:

3
a 1
["a", "1"]
b 2
["b", "2"]
c 3
["c", "3"] …
Run Code Online (Sandbox Code Playgroud)

hashmap rust borrowing

2
推荐指数
1
解决办法
726
查看次数

Rust 结构体上 getter 方法的借用问题

我对 Rust 很陌生,所以我仍在努力适应该语言的内存模型。

因此,当我在结构上cannot move out of borrowed content.构建方法时遇到错误。getter我不太明白为什么会这样,但它似乎与枚举上的某些特征有关。

enum Gender{
    Male,
    Female,
}
impl Default for Gender {
    fn default() -> Gender { Gender::Female }
}
impl Clone for Gender {
    fn clone(&self) -> Gender { *self }
}


#[derive(Default, Builder, Debug)]
#[builder(setter(into))]
struct ProfessorGroup {
    name: &'static str,
    gender:Gender,
    level:Levels,
    attrition_rate:f64,
    promotion_rate:f64,
    hiring_rate:f64,
    current_number:u32,
}
impl ProfessorGroup {
    pub fn get_gender(&self) -> Gender { self.gender }
    pub fn get_name(&self) -> &'static str {self.name}
    pub …
Run Code Online (Sandbox Code Playgroud)

struct memory-management rust borrowing

2
推荐指数
1
解决办法
951
查看次数

多个线程如何共享迭代器?

我一直在研究一个函数,它将使用Rust和线程将一堆文件从源复制到目标.我在线程共享迭代器时遇到了一些麻烦.我还不习惯借用系统:

extern crate libc;
extern crate num_cpus;

use libc::{c_char, size_t};
use std::thread;
use std::fs::copy;

fn python_str_array_2_str_vec<T, U, V>(_: T, _: U) -> V {
    unimplemented!()
}

#[no_mangle]
pub extern "C" fn copyFiles(
    sources: *const *const c_char,
    destinies: *const *const c_char,
    array_len: size_t,
) {
    let src: Vec<&str> = python_str_array_2_str_vec(sources, array_len);
    let dst: Vec<&str> = python_str_array_2_str_vec(destinies, array_len);
    let mut iter = src.iter().zip(dst);
    let num_threads = num_cpus::get();
    let threads = (0..num_threads).map(|_| {
        thread::spawn(|| while let Some((s, d)) = iter.next() {
            copy(s, d); …
Run Code Online (Sandbox Code Playgroud)

multithreading rust borrowing

2
推荐指数
1
解决办法
837
查看次数

如何修复这两个for循环以允许修改向量内容?

我试图在使用Vec<f64>Vec内部制作的矩阵上做一个循环,然后逐个改变它的元素.

我似乎无法使其发挥作用; 我对语法仍然太困惑了......

extern crate rand;

use std::ptr;
use std::mem;

use rand::Rng;

fn main() {
    let mut rng = rand::thread_rng();
    let mut v: Vec<Vec<f64>> = Vec::new();
    v.push(vec![0f64; 35]);
    v.push(vec![0f64; 35]);
    v.push(vec![0f64; 35]);
    v.push(vec![0f64; 35]);

    let len = v.len();
    for &el in &v {
        for q in &mut el {
            q = rng.gen::<f64>();
            println!("{}", q);
        }
        println!("{:?}", el);
    }
    println!("float: {}", rng.gen::<f64>());
    //println!("vec: {:?}, len: {}",v,len);
}
Run Code Online (Sandbox Code Playgroud)

编译器说:

error[E0308]: mismatched types
  --> src/main.rs:19:17
   |
19 |             q = rng.gen::<f64>(); …
Run Code Online (Sandbox Code Playgroud)

for-loop mutable rust borrowing

2
推荐指数
1
解决办法
116
查看次数

如何实现链表的前置而无需分配给新变量?

有人告诉我如何实现链表:

enum List {
    Cons(u32, Box<List>),
    Nil,
}

impl List {
    fn prepend(self, elem: u32) -> List {
        Cons(elem, Box::new(self))
    }
}
Run Code Online (Sandbox Code Playgroud)

当我想使用时prepend,我需要做以下事情:

list = list.prepend(1);
Run Code Online (Sandbox Code Playgroud)

但是,我想创建一个每次prepend返回时都不需要创建新变量的函数.我只想用以下方法更改list变量本身prepend:

list.prepend(1);
Run Code Online (Sandbox Code Playgroud)

这是我提出的一个实现,但它不对:

fn my_prepend(&mut self, elem: u32) {
    *self = Cons(elem, Box::new(*self));
}
Run Code Online (Sandbox Code Playgroud)

错误是:

error[E0507]: cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)

move-semantics rust data-structures borrowing

2
推荐指数
1
解决办法
102
查看次数

如何在不克隆字符串的情况下在 Rust 中构建灵活的多类型数据系统?

我想构建一个系统,其中不同类型的数据 ( i32, String, ...) 在修改数据的函数之间流动。例如,我想要一个add函数来获取“一些”数据并添加它。

add函数获取某种类型的东西,Value如果Value是 an i32,它将两个i32值相加,如果它是 type String,则返回一个组合了两个字符串的字符串。

我知道这对于模板编程(或在 Rust 中称为什么,我来自 C++)几乎是完美的,但在我的情况下,我想要处理这些东西的小代码块。

例如,使用f64and String,使用FloatandText作为名称,我有:

pub struct Float {
    pub min: f64,
    pub max: f64,
    pub value: f64,
}

pub struct Text {
    pub value: String,
}

pub enum Value {
    Float(Float),
    Text(Text),
}
Run Code Online (Sandbox Code Playgroud)

现在我想实现一个函数来获取一个应该是一个字符串的值并对其做一些事情,所以我实现了以下to_string()方法Value

impl std::string::ToString for Value {
    fn to_string(&self) -> …
Run Code Online (Sandbox Code Playgroud)

string polymorphism type-conversion rust borrowing

2
推荐指数
1
解决办法
538
查看次数

在使用条目模式时,如何改变HashMap的其他元素?

我想用a HashMap来缓存一个依赖于地图中其他条目的昂贵计算.条目模式仅提供对匹配值的可变引用,但不提供对其余的引用HashMap.我非常感谢有关更好地解决这个(不正确的)玩具示例的反馈:

use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};

fn compute(cache: &mut HashMap<u32, u32>, input: u32) -> u32 {
    match cache.entry(input) {
        Vacant(entry) => if input > 2 {
            // Trivial placeholder for an expensive computation.
            *entry.insert(compute(&mut cache, input - 1) +
                          compute(&mut cache, input - 2))
        } else {
            0
        },
        Occupied(entry) => *entry.get(),
    }
}

fn main() {
    let mut cache = HashMap::<u32, u32>::new();
    let foo = compute(&mut cache, 12);
    println!("{}", foo);
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

上面代码片段的问题是不 …

hashmap rust borrow-checker borrowing

2
推荐指数
1
解决办法
240
查看次数

为什么Rust阻止了多个可变引用?

像本主题中一样,Rust为什么阻止多个可变引用?我已经阅读了锈书中的一章,并且我了解到,当我们拥有多线程代码时,我们就可以避免数据竞争,但让我们看一下下面的代码:

fn main() {
    let mut x1 = String::from("hello");
    let r1 = &mut x1;
    let r2 = &mut x1;

    r1.insert(0, 'w');

}
Run Code Online (Sandbox Code Playgroud)

该代码不会同时运行,因此不会发生数据争用。当我创建新线程并且要在新线程中使用父线程中的变量时,还需要移动它,因此只有新线程才是父变量的所有者。

我看到的唯一原因是,程序员在成长过程中可能会迷失自己的代码。我们在多个地方可以修改一个数据,即使代码不是并行运行,我们也会遇到一些错误。

multithreading rust borrow-checker borrowing

2
推荐指数
1
解决办法
96
查看次数

可变借用互斥体内部的对象 - 如何重构?

我的许多功能中都有以下模式:

use std::sync::{Arc, Mutex};

struct State { 
    value: i32
}

fn foo(data: Arc<Mutex<State>>) {
    let state = &mut data.lock().expect("Could not lock mutex");
    // mutate `state`
}
Run Code Online (Sandbox Code Playgroud)

&mut *data.lock().expect("Could not lock mutex") 一遍又一遍地重复,所以我想将它重构为一个函数,以便编写类似

let state = get_state(data); 
Run Code Online (Sandbox Code Playgroud)

我尝试了以下方法:

fn get_state(data: &Arc<Mutex<State>>) -> &mut State {
    &mut data.lock().expect("Could not lock mutex")
}
Run Code Online (Sandbox Code Playgroud)

哪个无法编译:

错误:无法返回引用临时值的值

这让我相信data.state.lock().expect("...")价值回报。但是,我可以看到状态通过在这个 playground 上的多次foo调用而发生变化。

这里发生了什么?为什么我看似简单的重构编译失败?


编辑:

我希望以下内容也能正常工作:

fn get_state<'a>(data: &'a Arc<Mutex<State>>) -> &'a mut State {
    let state: &'a mut State = &mut …
Run Code Online (Sandbox Code Playgroud)

refactoring mutex rust borrowing

2
推荐指数
2
解决办法
988
查看次数