Skip to content
On this page

Move语义6: exercises/move_semantics/move_semantics6.rs

题目

rust
// move_semantics6.rs
//
// You can't change anything except adding or removing references.
//
// Execute `rustlings hint move_semantics6` or use the `hint` watch subcommand
// for a hint.

// I AM NOT DONE

fn main() {
    let data = "Rust is great!".to_string();

    get_char(data);

    string_uppercase(&data);
}

// Should not take ownership
fn get_char(data: String) -> char {
    data.chars().last().unwrap()
}

// Should take ownership
fn string_uppercase(mut data: &String) {
    data = &data.to_uppercase();

    println!("{}", data);
}

题目要求:只能添加或删除借用,其他的不能做任何修改。

题目解析

编译器提供的信息如下:

txt
⚠️  Compiling of exercises/move_semantics/move_semantics6.rs failed! Please try again. Here's the output:
error[E0382]: borrow of moved value: `data`
  --> exercises/move_semantics/move_semantics6.rs:15:22
   |
11 |     let data = "Rust is great!".to_string();
   |         ---- move occurs because `data` has type `String`, which does not implement the `Copy` trait
12 |
13 |     get_char(data);
   |              ---- value moved here
14 |
15 |     string_uppercase(&data);
   |                      ^^^^^ value borrowed here after move
   |
note: consider changing this parameter type in function `get_char` to borrow instead if owning the value isn't necessary
  --> exercises/move_semantics/move_semantics6.rs:19:19
   |
19 | fn get_char(data: String) -> char {
   |    --------       ^^^^^^ this parameter takes ownership of the value
   |    |
   |    in this function
help: consider cloning the value if the performance cost is acceptable
   |
13 |     get_char(data.clone());
   |                  ++++++++

error[E0716]: temporary value dropped while borrowed
  --> exercises/move_semantics/move_semantics6.rs:25:13
   |
24 | fn string_uppercase(mut data: &String) {
   |                               - let's call the lifetime of this reference `'1`
25 |     data = &data.to_uppercase();
   |     --------^^^^^^^^^^^^^^^^^^^- temporary value is freed at the end of this statement
   |     |       |
   |     |       creates a temporary value which is freed while still in use
   |     assignment requires that borrow lasts for `'1`

error: aborting due to 2 previous errors

Some errors have detailed explanations: E0382, E0716.
For more information about an error, try `rustc --explain E0382`.

获取到的错误信息如下:

  • get_char(data)函数时data已经转移了所有权
  • 后面string_uppercase(&data)又对data进行借用,因为上一步所有权已经转移,此处报错。

我们将其调换以下即可:

rust
fn main() {
    let data = "Rust is great!".to_string();

    get_char(data);  
    get_char(&data); 

    string_uppercase(&data); 
    string_uppercase(data); 
}

// Should not take ownership
fn get_char(data: String) -> char { 
fn get_char(data: &String) -> char { 
    data.chars().last().unwrap()
}

// Should take ownership
fn string_uppercase(mut data: &String) { 
fn string_uppercase(mut data: String) { 
    data = &data.to_uppercase(); 
    data = data.to_uppercase(); 

    println!("{}", data);
}

参考资料

Powered by VitePress