文章

Rust学习笔记(3) - 结构体

struct,或者 structure,是一个自定义数据类型,允许命名和包装多个相关的值,从而形成一个有意义的组合,就像面向对象语言中,一个对象中的各个属性

定义、实例化、使用结构体

这里展示如何定义并且实例化一个结构体,然后对结构体的字段内容进行调整,并输出到控制台(这里演示了#[derive(Debug)]注解的用法和如何调用println!()打印结构体)。另外还演示了如何用函数处理具有重复字段值的结构体的初始化,以及使用一个已有的结构体实例的字段来快速初始化一个新的结构体实例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#[derive(Debug)]
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

fn main() {
    let mut new_user1 = build_user(
        String::from("narancia@86.outlook.com"),
        String::from("用户名"),
    );

    let new_user2 = User {
        sign_in_count: 66,
        ..new_user1
    };

    new_user1.username = String::from("用户名");
    new_user1.email = String::from("narancia@86.outlook.com");
    println!("{:#?}", new_user1);
    // User {
    //     username: "用户名",
    //     email: "narancia@86.outlook.com",
    //     sign_in_count: 1,
    //     active: true,
    // }

    println!("{:#?}", new_user2);
    // User {
    //     username: "用户名",
    //     email: "narancia@86.outlook.com",
    //     sign_in_count: 66,
    //     active: true,
    // }
}

没有命名字段的元组结构体

1
2
3
4
5
6
7
8
fn main() {
    #[derive(Debug)]
    struct Color(i32, i32, i32);

    let black = Color(0, 0, 0);
    println!("{:?}", black);
    // Color(0, 0, 0)
}

元组结构体(tuple structs)有结构体名称提供的含义,但没有具体的字段名,只有字段的类型,当想给整个元组起一个名字时,这是很有用的

结构体数据的所有权

可以看到,我们定义结构体时,都用了自身拥有所有权的String类型而不是字符串slice类型&str,因为我们想让这个结构体拥有它所有的数据,而不被其他对象拥有的数据的引用,如果想要那要做的话需要用上生命周期(lifetimes),这在之后会学习到,生命周期确保结构体引用的数据的有效性跟结构体本身保持一致

方法语法

这里演示了如何在impl块中定义方法和关联函数associated functions),以及如何使用它们。所谓关联函数,它们不作用于一个结构体的实例,我们已经用过String::from关联函数了,另外值得注意的是,对于同一个结构体,可以定义多个impl

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#[derive(Debug)]
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

impl User {
    fn introduce(&self) -> String {
        "My Name is ".to_string() + &self.username + ", email is " + &self.email
    }

    fn new_man() -> User {
        User {
            username: "new_man".to_string(),
            email: "new@email.com".to_string(),
            sign_in_count: 12,
            active: true,
        }
    }
}

fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

fn main() {
    let mut new_user1 = build_user(
        String::from("narancia@86.outlook.com"),
        String::from("用户名"),
    );

    println!("{}", new_user1.introduce());
    // My Name is 用户名, email is narancia@86.outlook.com

    println!("{:#?}", User::new_man());
    // User {
    //     username: "new_man",
    //     email: "new@email.com",
    //     sign_in_count: 12,
    //     active: true,
    // }
}
本文由作者按照 CC BY 4.0 进行授权