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) 以下代码因借用错误而失败:
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。
以下代码无法编译,因为编译器无法保证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) 示例代码:
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)
如果赋值相同,为什么生锈不释放内存而是重新使用它,否则分配新的内存块?
以下测试程序无法编译:
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_string该to_string()方法,程序将编译并运行。to_string()应该是一个无操作方法,因为已经my_string是String。然而,这个程序运行良好。
fn f1( string: String) {
println!("{}", string );
}
fn f2( string: …Run Code Online (Sandbox Code Playgroud) &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 语句进行更奇特的借用是否存在隐藏的不安全性?或者这只是生活质量改善融入某些地方而不是其他地方的一个例子?我确信了解类型系统的人有答案,但互联网上关于这种行为小怪癖的信息似乎很少。
我有一个使用 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) 我一直在学习 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)
有人可以解释为什么只有第二个有效吗?
borrow ×8
rust ×8
reference ×3
asynchronous ×1
lifetime ×1
match ×1
memory ×1
mutable ×1
rust-tokio ×1
swap ×1