标签: borrow

借用变量时的 Rust 生命周期语法

Rust 新手,试图自学等等。我陷入了一生的问题。我能找到的最接近的已发布问题是:

参数要求借用 _ 来表示“静态” - 我该如何解决这个问题?

我正在玩的小项目定义了两个结构,Agent并且Item

Agent除其他内容外,该结构还包含以下行:

pub inventory: HashMap<String, &'static Item>,

此外,我还实现了这段代码:

impl Agent {
    
pub fn take_item(&mut self, item: &'static Item) -> std::result::Result<(), TestError> {
        if item.can_be_taken {
            if self.can_reach_item(item) {
                self.inventory.insert(item.name.to_string(), item);
                return Ok(());
            } else {
                return Err(ItemOutOfReachError {});
            }
        } else {
            return Err(ItemCannotBeTakenError {});
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我写了一个单元测试,其中包括这一行

let result = test_agent.take_item(&test_item);
Run Code Online (Sandbox Code Playgroud)

我知道某个地方有错误,因为编译器告诉我:

  --> src/agent.rs:57:47
   |
57 |             let result = test_agent.take_item(&test_item);
   |                          ---------------------^^^^^^^^^^-
   |                          |                    | …
Run Code Online (Sandbox Code Playgroud)

reference lifetime rust borrow

6
推荐指数
1
解决办法
3081
查看次数

当没有发生借用重叠时,为什么会出现借用错误?

以下代码因借用错误而失败:

extern crate chrono; // 0.4.6

fn main() {
    let mut now = chrono::Local::today();
    now = std::mem::replace(&mut now, now.succ());
}
Run Code Online (Sandbox Code Playgroud)

错误是:

extern crate chrono; // 0.4.6

fn main() {
    let mut now = chrono::Local::today();
    now = std::mem::replace(&mut now, now.succ());
}
Run Code Online (Sandbox Code Playgroud)

为什么这里会出现借用错误?now.succ()返回一个新对象,看起来调用succ()应该返回新对象,在可变借用发生之前结束不可变借用replace

rust borrow

5
推荐指数
1
解决办法
111
查看次数

当使用 tokio::spawn 和带有可变引用的 future 时,“借用的值存在的时间不够长”

以下代码无法编译,因为编译器无法保证hashmap_of_lists其寿命足够长。我无法克服这一点。

我尝试过使用ArcandMutex但由于内部some_func使用的异步方式,我遇到了其他问题Mutex

use futures; // 0.3.5
use std::collections::HashMap;
use tokio; // 0.2.21

async fn some_func(_some_slice: &mut [String]) {}

#[tokio::main]
async fn main() {
    let mut hashmap_of_lists = HashMap::<String, Vec<String>>::new();
    let mut join_handles = Vec::new();

    for (_, value) in hashmap_of_lists.iter_mut() {
        let future = some_func(value);
        let join_handle = tokio::task::spawn(future);
        join_handles.push(join_handle);
    }

    futures::future::join_all(join_handles).await;
}
Run Code Online (Sandbox Code Playgroud)

我收到这个错误

error[E0597]: `hashmap_of_lists` does not live long enough
  --> src/main.rs:12:23
   |
12 |     for (_, value) in hashmap_of_lists.iter_mut() …
Run Code Online (Sandbox Code Playgroud)

asynchronous reference rust rust-tokio borrow

5
推荐指数
0
解决办法
2070
查看次数

为什么Rust重复使用具有相同值的内存

示例代码:

fn main() {
    let mut y = &5; // 1

    println!("{:p}", y);

    {
        let x = &2; // 2
        println!("{:p}", x);
        y = x;
    }

    y = &3; // 3
    println!("{:p}", y);
}
Run Code Online (Sandbox Code Playgroud)

如果第三次分配包含&3代码输出:

0x558e7da926a0
0x558e7da926a4
0x558e7da926a8
Run Code Online (Sandbox Code Playgroud)

如果第三个分配包含&2(与第二个分配相同的值),则代码输出:

0x558e7da926a0
0x558e7da926a4
0x558e7da926a4
Run Code Online (Sandbox Code Playgroud)

如果第三个分配包含&5(与第一个分配相同的值),则代码输出:

0x558e7da926a0
0x558e7da926a4
0x558e7da926a0
Run Code Online (Sandbox Code Playgroud)

如果赋值相同,为什么生锈不释放内存而是重新使用它,否则分配新的内存块?

memory rust borrow

4
推荐指数
1
解决办法
148
查看次数

为什么在字符串上调用 .to_string() 可以避免移动错误?不是说无操作吗?

以下测试程序无法编译:

fn f1( string: String) {
    println!("{}", string );
}

fn f2( string: String) {
    println!("{}", string );
}

fn main() {
    let my_string: String = "ABCDE".to_string();
    f1( my_string );
    f2( my_string );
}
Run Code Online (Sandbox Code Playgroud)

它会生成预期的错误:

11 |     f1( my_string );
   |         --------- value moved here
12 |     f2( my_string );
   |         ^^^^^^^^^ value used here after move
Run Code Online (Sandbox Code Playgroud)

但是,如果您使用my_stringto_string()方法,程序将编译并运行。to_string()应该是一个无操作方法,因为已经my_stringString。然而,这个程序运行良好。

fn f1( string: String) {
    println!("{}", string );
}

fn f2( string: …
Run Code Online (Sandbox Code Playgroud)

rust borrow

3
推荐指数
1
解决办法
188
查看次数

为什么 match 语句对引用类型比函数参数更挑剔?

&str在 Rust 中,人们经常看到以参数为参数的函数。

fn foo(bar: &str) {
    println!("{}", bar);
}
Run Code Online (Sandbox Code Playgroud)

String当调用这样的函数时,通过引用 a 作为参数传递它是完全可以的。

let bar = String::from("bar");
foo(&bar);
Run Code Online (Sandbox Code Playgroud)

严格来说,传递的参数是 an&String并且函数期望是 an &str,但是 Rust(正如人们所希望的那样)只是计算出来并且一切正常。然而,match 语句的情况并非如此。bar如果我尝试在匹配语句中使用与之前相同的变量,则天真的用法将无法编译:

match &bar {
    "foo" => println!("foo"),
    "bar" => println!("bar"),
    _ => println!("Something else")
};
Run Code Online (Sandbox Code Playgroud)

Rustc 抱怨它本来期待一个,&str但收到了一个&String。问题和解决方案都非常明显:只需bar更明确地借用.as_str(). 但这让我想到了真正的问题:为什么会这样?

如果 Rust 能够发现在函数参数的情况下an&String可以简单地转换为 an ,为什么它不能用 match 语句做同样的事情呢?&str这是类型系统限制的结果,还是使用 match 语句进行更奇特的借用是否存在隐藏的不安全性?或者这只是生活质量改善融入某些地方而不是其他地方的一个例子?我确信了解类型系统的人有答案,但互联网上关于这种行为小怪癖的信息似乎很少。

reference match rust borrow

3
推荐指数
1
解决办法
85
查看次数

为什么我得到“不能一次多次借用 `arr[_]` 作为可变对象”?

我有一个使用 Rust 创建冒泡排序的编程作业。我在 Rust 方面确实没有太多经验,所以这对我来说有点困难:

fn main() {
    println!("Sort numbers ascending");
    let num:[i32; 10] = [4, 65, 2, -31, 0, 99, 2, 83, 782, 1];
    println!("Before: {:?}", num);
    bubble_sort( num);
    println!("After: {:?}\n", num);
}

fn swap( a: &mut i32, b: &mut i32){
    let tmp: i32 = *b;
    *b=*a;
    *a=tmp;
}

fn bubble_sort(mut arr: [i32; 10]) {
    for i in 0..arr.len() {
        for j in 0..arr.len() - 1 - i {
            if arr[j] > arr[j + 1] {
                swap( &mut arr[j], …
Run Code Online (Sandbox Code Playgroud)

swap mutable rust borrow

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

为什么这被认为是借用的

我一直在学习 Rust,并且一直在尝试学习借用检查器的工作原理,但我遇到了这两个例子,我不明白为什么只有其中一个被认为是借用的:

fn main() {
    let mut x = String::from("aa ab");

    let y = first_word(&x);

    x.clear(); //Error cannot borrow X

    println!("{y}");


}

//Returns an i32 reference
fn first_word(s: &String) -> &i32 {
    return &32;
}   
Run Code Online (Sandbox Code Playgroud)
fn main() {
    let mut x = String::from("aa ab");

    let y = first_word(&x);

    x.clear(); //Everything is fine

    println!("{y}");


}

//Returns an i32
fn first_word(s: &String) -> i32 {
    return 32;
}   
Run Code Online (Sandbox Code Playgroud)

有人可以解释为什么只有第二个有效吗?

rust borrow-checker borrow

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