Rust编译时常出现的错误


参考自 通过Rust编译时出现的错误来学习Rust

搜索时 将``之间的内容替换掉或去掉

can’t compare str with &str


“can’t compare str with &str“ 错误通常发生在尝试将一个字符串字面值(&str)与一个字符串对象(str)进行比较时。这是因为它们的类型不匹配。

要解决这个问题,你需要确保比较的两个对象具有相同的类型。有几种方法可以解决这个问题:

  1. 将字符串字面值转换为字符串对象:如果你有一个字符串字面值和一个字符串对象需要进行比较,你可以将字符串字面值转换为字符串对象。你可以使用 to_string()to_owned() 方法将字符串字面值转换为 String 对象,然后再进行比较。

    1
    2
    3
    4
    5
    6
    let str_literal = "Hello";
    let str_object = "Hello".to_string();

    if str_literal == str_object {
    // 进行比较操作
    }
  2. 将字符串对象转换为字符串切片:如果你有一个字符串对象和一个字符串切片需要进行比较,你可以将字符串对象转换为字符串切片,以匹配类型。你可以使用 as_str() 方法将 String 对象转换为 &str 类型。

    1
    2
    3
    4
    5
    6
    let str_object = String::from("Hello");
    let str_slice: &str = str_object.as_str();

    if str_slice == "Hello" {
    // 进行比较操作
    }

通过上述方法,你可以将两个不同类型的字符串进行适当的类型转换,以便进行比较操作。



cannot assign twice to immutable variable x


不可变变量不能被分配两次

1
2
3
4
5
6
fn main() {
let x = 5; // solution: let mut x = 5;
println!("The value of x is {}", x);
x = 6;
println!("The value of x is {}", x);
}

error[E0384]: cannot assign twice to immutable variable x

1
2
3
4
5
6
7
8
9
10
 --> src/main.rs:4:5
|
2 | let x = 5; // solution: let mut x = 5;
| -
| |
| first assignment to `x`
| help: consider making this binding mutable: `mut x`
3 | println!("The value of x is {}", x);
4 | x = 6;
| ^^^^^ cannot assign twice to immutable variable



consider giving guess a type


编译器无法推断出变量的类型,考虑为这个变量声明一个类型

1
2
3
fn main() {
let guess = "32".trim().parse().expect("Not a number!");// solution: let guess:i32 = "32".trim().parse().expect("Not a number!");
}

error[E0282]: type annotations needed

1
2
3
4
 --> src/main.rs:2:9
|
2 | let guess = "32".trim().parse().expect("Not a number!");// solution: let guess:i32 = "32".trim().parse().expect("Not a number!");
| ^^^^^ consider giving `guess` a type



index out of bounds: the length is 2 but the index is 2


索引超出范围

1
2
3
4
5
fn main() {
let elements = [1, 2];
let index = 2;
println!("The value of elements is {}", elements[index]);
}
1
2
3
4
5
6
7
error: this operation will panic at runtime
--> src/main.rs:4:45
|
4 | println!("The value of elements is {}", elements[index]);
| ^^^^^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 2
|
= note: `#[deny(unconditional_panic)]` on by default



let expressions are not supported here


期待是表达式,但发现是语句

1
2
3
fn main() {
let valueA = (let valueB = 6);
}

expected expression, found statement (let)

1
2
3
4
5
6
7
8
9
10
11
12
error: `let` expressions are not supported here
--> src/main.rs:2:19
|
2 | let valueA = (let valueB = 6);
| ^^^^^^^^^^^^^^
|
= note: only supported directly in conditions of `if` and `while` expressions
note: `let`s wrapped in parentheses are not supported in a context with let chains
--> src/main.rs:2:19
|
2 | let valueA = (let valueB = 6);
| ^^^^^^^^^^^^^^



mismatched types


类型不匹配

期望是 i32, 但发现是空元组

1
2
3
4
5
6
7
8
fn main() {
let x = plus_value(5);
println!("The value of x {}", x);
}

fn plus_value(value: i32) -> i32 {
value + 5;
}

error[E0308]: mismatched types

移除value + 5;后的分号就行了

1
2
3
4
5
6
7
8
 --> src/main.rs:6:30
|
6 | fn plus_value(value: i32) -> i32 {
| ---------- ^^^ expected `i32`, found `()`
| |
| implicitly returns `()` as its body has no tail or `return` expression
7 | value + 5;
| - help: remove this semicolon ^^^^^^^^^^^^^^

类型不匹配

期待是布尔值,但发现是整型

1
2
3
4
5
6
7
8
fn main() {
let number = 3;
if number { // solution: if number == 3 {
println!("continue was true");
} else {
println!("continue was false");
}
}

error[E0308]: mismatched types

1
2
3
4
5
 expected `bool`, found integer
--> src/main.rs:3:8
|
3 | if number {
| ^^^^^^ expected `bool`, found integer



if and else have incompatible types


if和else有不一样(不兼容)的类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn main() {
let number = 3;
if number == 3 {
println!("continue was true");
} else if number == 2 {
println!("continue was false");
}

let value = if number == 3 {
"The number is 3"
} else {
5 // solution: "5"
};
}

error[E0308]: if and else have incompatible types

1
2
3
4
5
6
7
8
9
10
11
  --> src/main.rs:12:9
|
9 | let value = if number == 3 {
| _________________-
10 | | "The number is 3"
| | ----------------- expected because of this
11 | | } else {
12 | | 5 // solution: "5"
| | ^ expected `&str`, found integer
13 | | };
| |_____- `if` and `else` have incompatible types



borrow of moved value: string1


(堆上的变量)string1的所有权已移动

1
2
3
4
5
fn main() {
let string1 = String::from("Hello");
let string2 = string1;
println!("string1 {}", string1);
}

error[E0382]: borrow of moved value: string1

1
2
3
4
5
6
7
8
9
10
11
12
 --> src/main.rs:4:28
|
2 | let string1 = String::from("Hello");
| ------- move occurs because `string1` has type `String`, which does not implement the `Copy` trait
发生移动,是因为类型String不具有Copy特性
3 | let string2 = string1;
| ------- value moved here
4 | println!("string1 {}", string1);
| ^^^^^^^ value borrowed here after move
value移动后这里又再次使用
|
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
fn main() {
let mut s = String::new();

let data = "initial contents";
let s = data.to_string();

// the method also works on a literal directly:
let s = "initial contents".to_string();

let s1 = String::from("Hello, ");
let s2 = String::from("world!");
let s3 = s1 + &s2; /// 这里的s1借出去了,后s1无法使用
println!("s3 {} s1 {}", s3, s1);
}


error[E0382]: borrow of moved value: string1

1
2
3
4
5
6
7
8
9
10
11
  --> src/main.rs:13:33
|
10 | let s1 = String::from("Hello, ");
| -- move occurs because `s1` has type `String`, which does not implement the `Copy` trait
11 | let s2 = String::from("world!");
12 | let s3 = s1 + &s2; /// 这里的s1借出去了,后s1无法使用
| -- value moved here
13 | println!("s3 {} s1 {}", s3, s1);
| ^^ value borrowed here after move
|
= note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info)

Rust所有权三原则:

  • Each value in Rust has a variable that’s called its owner. (Rust中每一个变量都有一个所有者)

  • There can only be one owner at a time.(在任一时刻,所有者有且仅有一个)

  • When the owner goes out of scope, the value will be dropped.(当所有者离开其作用域后,它所拥有的数据会被释放)




cannot borrow s as mutable more than once at a time


不能多次借用s作为一个可变引用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
fn main() {
let mut s = String::from("Hello");
push_str(&mut s);
// println!("{}", s);

let r1 = &mut s; // 一次声明只能一次可变引用
let r2 = &mut s;
println!("r1 {}", r1);

{
let r1 = &mut s;
println!("r1 {}", r1);
}
{
let r2 = &mut s;
println!("r2 {}", r2);
}
}

fn push_str(s: &mut String) {
s.push_str(" World!");
}

error[E0499]: cannot borrow s as mutable more than once at a time

1
2
3
4
5
6
7
8
 --> src/main.rs:7:14
|
6 | let r1 = &mut s; // 一次声明只能一次可变引用
| ------ first mutable borrow occurs here
7 | let r2 = &mut s;
| ^^^^^^ second mutable borrow occurs here
8 | println!("r1 {}", r1);
| -- first borrow later used here



cannot borrow s as mutable because it is also borrowed as immutable


不能借用 s 作为可变的,因为它也被借用为不可变的

1
2
3
4
5
6
7
8
9
fn main() {
let mut s = String::from("Hello");

let r1 = &s;
let r2 = &s;
let r3 = &mut s;

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

error[E0502]: cannot borrow s as mutable because it is also borrowed as immutable

1
2
3
4
5
6
7
8
9
10
 --> src/main.rs:6:14
|
4 | let r1 = &s;
| -- immutable borrow occurs here
5 | let r2 = &s;
6 | let r3 = &mut s;
| ^^^^^^ mutable borrow occurs here
7 |
8 | println!("r1 {}", r1);
| -- immutable borrow later used here

1
2
3
4
5
6
fn main() {
let mut v = vec![1, 2, 3, 4, 5];
let first = &v[0];
v.push(6);
println!("The first element is: {}", first); // solution:This line of code moves to the previous line
}

error[E0502]: cannot borrow s as mutable because it is also borrowed as immutable

1
2
3
4
5
6
7
8
9
 --> src/main.rs:4:5
|
3 | let first = &v[0];
| - immutable borrow occurs here
4 | v.push(6);
| ^^^^^^^^^ mutable borrow occurs here
5 | println!("The first element is: {}", first); // solution:This line of code moves to the previous line
| ----- immutable borrow later used here


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn main() {
let mut s = String::from("Hello World!");
let world = first_word(&s);
s.clear();
println!("s {} world {}", s, world);
}

fn first_word(s: &String) -> &str {
let bytes = s.as_bytes();
for (i, &item) in bytes.iter().enumerate() {
if item == b' ' {
return &s[0..i];
}
}
return &s[..];
}

error[E0502]: cannot borrow s as mutable because it is also borrowed as immutable

1
2
3
4
5
6
7
8
 --> src/main.rs:4:5
|
3 | let world = first_word(&s);
| -- immutable borrow occurs here
4 | s.clear();
| ^^^^^^^^^ mutable borrow occurs here
5 | println!("s {} world {}", s, world);
| ----- immutable borrow later used here



missing lifetime specifier


缺少生命周期说明符的

1
2
3
4
5
6
7
8
9
fn main() {
let Hello = dangle();
}

// 悬垂引用
fn dangle() -> &String {
let value = String::from("Hello");
&value
}

error[E0106]: missing lifetime specifier

1
2
3
4
5
6
7
8
9
10
 --> src/main.rs:6:16
|
6 | fn dangle() -> &String {
| ^ expected named lifetime parameter
|
= help: this function's return type contains a borrowed value, but there is no value for it to be borrowed from
help: consider using the `'static` lifetime
|
6 | fn dangle() -> &'static String {
| ~~~~~~~~



on-exhaustive patterns: &None not covered


详尽的模式:&None 未涵盖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
fn plus_one(x: &Option<i32>) -> Option<i32> {
match x {
Some(i) => Some(i + 1),
}
}

fn main() {
let a: i32 = 1;
let b: Option<i32> = Some(5);
//let c = a + b; /// 错误
//println!("{}", c);

plus_one(&b);
}

error[E0004]: non-exhaustive patterns: &None not covered

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
   --> src/main.rs:2:11
|
2 | match x {
| ^ pattern `&None` not covered
|
note: `Option<i32>` defined here
--> /Users/fliter/.rustup/toolchains/nightly-aarch64-apple-darwin/lib/rustlib/src/rust/library/core/src/option.rs:522:5
|
518 | / pub enum Option<T> {
519 | | /// No value.
520 | | #[lang = "None"]
521 | | #[stable(feature = "rust1", since = "1.0.0")]
522 | | None,
| | ^^^^ not covered
... |
526 | | Some(#[stable(feature = "rust1", since = "1.0.0")] T),
527 | | }
| |_-
= note: the matched value is of type `&Option<i32>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
|
3 ~ Some(i) => Some(i + 1),
4 ~ &None => todo!(),
|

on-exhaustive patterns: &None not covered


***

1

error[E0277]:

the ? operator can only be used in a function that returns Result or Option (or another type that implements FromResidual),

the trait bound Opts: From<&str> is not satisfied


^ cannot use the ? operator in a function that returns ()