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

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

cannot assign twice to immutable variable x

不能复制两次不可变x

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);
}

consider giving guess a type

尝试给guess类型

let guess = "32".trim().parse().expect("Not a number!");
/// solution: let guess:i32 = "32".trim().parse().expect("Not a number!");

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

越界

fn main() {
    let elements = [1, 2];
    let index = 2;
    println!("The value of elements is {}", elements[index]);
    
    // review
    let value:i8;
    let value:i32;
    let value:i64;
    let value:isize;
    let value:u8;
    let value:u32;
    let value:u64;
    let value:usize;
    let value = 92_222;
    let value = 0xfff;
    let value = 0o77;
    let value = 0b1111_0000;
    let value = b'A';
    let value: f64 = 2.0;
    let value: f32 = 3.0;
    let value:bool = true;
    let value:char = 'Z';
    let value: (i32, bool) = (1, true);
    let value1 = value.0;
    let value2 = value.1;
    let (value, valueB) = value;
    let value:[i32; 3] = [1, 2, 3];
    let value = [3; 3]; // [3, 3, 3]
    let value1 = value[0];
}

expected expression, found statement (let)

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

let valueA = (let valueB = 6);

mismatched types

类型不匹配

fn main() {
    let x = plus_value(5);
    println!("The value of x {}", x);
}

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

/// 错误如下
 fn plus_value(value: i32) -> i32 {
    ----------                ^^^ expected `i32`, found `()` 期望是 i32, 但是发现是空元组
    |
    implicitly returns `()` as its body has no tail or `return` expression
     value + 5;
              - help: consider removing this semicolon 帮助: 建议是移除分号

expected bool, found integer

fn main() {
    let number = 3;
    if number {	// solution: if number == 3 {
        println!("continue was true");
    }
    else {
        println!("continue was false");
    }
}

if and else have incompatible types

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"
    };
}

Loop

fn main() {
    let mut couter = 0;
    let result = loop {
        couter += 1;
        if couter == 10 {
            break couter * 2;
        }
    };

    println!("result: {}", result);

    while couter > 0 {
        println!("couter: {}", couter);
        couter -= 1;
    }

    let elements = [1, 2];
    for element in elements.iter() {
        println!("element: {}", element);
    }

    for number in (0..4).rev() {
        println!("number: {}", number);
    }
}

borrow of moved value: xxx

// error
let string1 = String::from("Hello");
    ------- move occurs because `string1` has type `String`, which does not implement the `Copy` trait
    发生移动,是因为类型String不具有Copy特性
let string2 = string1;
              ------- value moved here
println!("string1 {}", string1);
                       ^^^^^^^ value borrowed here after move
                       value移动后这里又再次使用

cannot borrow s as mutable more than once at a time

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!");
}

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

fn main() {
    let mut s = String::from("Hello");

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

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

expected named lifetime parameter

fn main() {
    let Hello = dangle();
}

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

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

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[..]
}

Struct

fn main() {
    let user1 = User {
        username: String::from("someone"),
        email: String::from("someone@qq.com"),
    };

    let user2 = User {
        username: user1.username,
        ..user1
    };
}

fn build_user(username: String, email: String,) -> User {
    return User {
        username, email,
    };
}

struct User {
    username: String,
    email: String,
}
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
    
    fn square(size: u32) -> Rectangle {
        Rectangle { width: size, height: size}
    }
}

impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width == other.width && self.height == other.height
    }
}

fn main() {
    let rect = Rectangle { width: 30, height: 30 };
    println!("rect {:?} area {:?}", rect, rect.area());
}

struct

enum IpAddrKind {
    V4,
    V6,
}

struct IpAddr {
    kind: IpAddrKind,
    address: String,
}

fn main() {
    let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
    };

    let loopback = IpAddr {
        kind: IpAddrKind::V6,
        address: String::from("::1"),
    };
}

Enum

enum IpAddr {
    V4(String),
    V6(String),
}

let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}


struct QuitMessage; // unit struct
struct MoveMessage {
    x: i32,
    y: i32,
}
struct WriteMessage(String); // tuple struct
struct ChangeColorMessage(i32, i32, i32); // tuple struct


impl Message {
    fn call(&self) {
        // method body would be defined here
    }
}
let m = Message::Write(String::from("hello"));
m.call();

non-exhaustive patterns: &None not covered


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);
}

If let

fn main() {
    let some_u8_value = Some(3);
    match some_u8_value {
        Some(3) => println!("Three"),
        _ => ()
    }

    if let Some(4) = some_u8_value {
        println!("Three!");
    }else {
        println!("No match!");
    }
}

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

cannot assign twice to immutable variable x

不能复制两次不可变x

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);
}

consider giving guess a type

尝试给guess类型

let guess = "32".trim().parse().expect("Not a number!");
/// solution: let guess:i32 = "32".trim().parse().expect("Not a number!");

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

越界

fn main() {
    let elements = [1, 2];
    let index = 2;
    println!("The value of elements is {}", elements[index]);
    
    // review
    let value:i8;
    let value:i32;
    let value:i64;
    let value:isize;
    let value:u8;
    let value:u32;
    let value:u64;
    let value:usize;
    let value = 92_222;
    let value = 0xfff;
    let value = 0o77;
    let value = 0b1111_0000;
    let value = b'A';
    let value: f64 = 2.0;
    let value: f32 = 3.0;
    let value:bool = true;
    let value:char = 'Z';
    let value: (i32, bool) = (1, true);
    let value1 = value.0;
    let value2 = value.1;
    let (value, valueB) = value;
    let value:[i32; 3] = [1, 2, 3];
    let value = [3; 3]; // [3, 3, 3]
    let value1 = value[0];
}

expected expression, found statement (let)

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

let valueA = (let valueB = 6);

mismatched types

类型不匹配

fn main() {
    let x = plus_value(5);
    println!("The value of x {}", x);
}

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

/// 错误如下
 fn plus_value(value: i32) -> i32 {
    ----------                ^^^ expected `i32`, found `()` 期望是 i32, 但是发现是空元组
    |
    implicitly returns `()` as its body has no tail or `return` expression
     value + 5;
              - help: consider removing this semicolon 帮助: 建议是移除分号

expected bool, found integer

fn main() {
    let number = 3;
    if number {	// solution: if number == 3 {
        println!("continue was true");
    }
    else {
        println!("continue was false");
    }
}

if and else have incompatible types

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"
    };
}

Loop

fn main() {
    let mut couter = 0;
    let result = loop {
        couter += 1;
        if couter == 10 {
            break couter * 2;
        }
    };

    println!("result: {}", result);

    while couter > 0 {
        println!("couter: {}", couter);
        couter -= 1;
    }

    let elements = [1, 2];
    for element in elements.iter() {
        println!("element: {}", element);
    }

    for number in (0..4).rev() {
        println!("number: {}", number);
    }
}

borrow of moved value: xxx

// error
let string1 = String::from("Hello");
    ------- move occurs because `string1` has type `String`, which does not implement the `Copy` trait
    发生移动,是因为类型String不具有Copy特性
let string2 = string1;
              ------- value moved here
println!("string1 {}", string1);
                       ^^^^^^^ value borrowed here after move
                       value移动后这里又再次使用

cannot borrow s as mutable more than once at a time

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!");
}

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

fn main() {
    let mut s = String::from("Hello");

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

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

expected named lifetime parameter

fn main() {
    let Hello = dangle();
}

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

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

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[..]
}

Struct

fn main() {
    let user1 = User {
        username: String::from("someone"),
        email: String::from("someone@qq.com"),
    };

    let user2 = User {
        username: user1.username,
        ..user1
    };
}

fn build_user(username: String, email: String,) -> User {
    return User {
        username, email,
    };
}

struct User {
    username: String,
    email: String,
}
#[derive(Debug)]
struct Rectangle {
    width: u32,
    height: u32,
}

impl Rectangle {
    fn area(&self) -> u32 {
        self.width * self.height
    }
    
    fn square(size: u32) -> Rectangle {
        Rectangle { width: size, height: size}
    }
}

impl Rectangle {
    fn can_hold(&self, other: &Rectangle) -> bool {
        self.width == other.width && self.height == other.height
    }
}

fn main() {
    let rect = Rectangle { width: 30, height: 30 };
    println!("rect {:?} area {:?}", rect, rect.area());
}

struct

enum IpAddrKind {
    V4,
    V6,
}

struct IpAddr {
    kind: IpAddrKind,
    address: String,
}

fn main() {
    let home = IpAddr {
        kind: IpAddrKind::V4,
        address: String::from("127.0.0.1"),
    };

    let loopback = IpAddr {
        kind: IpAddrKind::V6,
        address: String::from("::1"),
    };
}

Enum

enum IpAddr {
    V4(String),
    V6(String),
}

let home = IpAddr::V4(String::from("127.0.0.1"));
let loopback = IpAddr::V6(String::from("::1"));

enum Message {
    Quit,
    Move { x: i32, y: i32 },
    Write(String),
    ChangeColor(i32, i32, i32),
}


struct QuitMessage; // unit struct
struct MoveMessage {
    x: i32,
    y: i32,
}
struct WriteMessage(String); // tuple struct
struct ChangeColorMessage(i32, i32, i32); // tuple struct


impl Message {
    fn call(&self) {
        // method body would be defined here
    }
}
let m = Message::Write(String::from("hello"));
m.call();

non-exhaustive patterns: &None not covered


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);
}

If let

fn main() {
    let some_u8_value = Some(3);
    match some_u8_value {
        Some(3) => println!("Three"),
        _ => ()
    }

    if let Some(4) = some_u8_value {
        println!("Three!");
    }else {
        println!("No match!");
    }
}
上一篇:Montgomery 算法流程


下一篇:理解内存对齐