Rust

5.1 - 结构体 - 定义并实例化结构体

2019-08-29  本文已影响0人  空乱木

原文链接:https://kaisery.github.io/trpl-zh-cn/ch05-01-defining-structs.html

和元组一样,结构体的每一部分可以是不同类型。

示例 5-1:User 结构体定义

struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

示例 5-2:创建 User 结构体的实例
实例中字段的顺序不需要和它们在结构体中声明的顺序一致。

fn main() {
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

let user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};
}

如果结构体的实例是可变的,我们可以使用点号并为对应的字段赋值。
示例 5-3 展示了如何改变一个可变的 User 实例 email 字段的值:

fn main() {
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

let mut user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

user1.email = String::from("anotheremail@example.com");
}

注意整个实例必须是可变的;Rust 并不允许只将某个字段标记为可变。

示例 5-4:build_user 函数获取 email 和用户名并返回 User 实例

fn main() {
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

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

变量与字段同名时的字段初始化简写语法
字段初始化简写语法

示例 5-5:build_user 函数使用了字段初始化简写语法,因为 email 和 username 参数与结构体字段同名

fn main() {
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,
    }
}
}

结构体更新语法从其他实例创建实例
示例 5-6 展示了不使用更新语法时,如何在 user2 中创建一个新 User 实例。我们为 email 和 username 设置了新的值,其他值则使用了实例 5-2 中创建的 user1 中的同名值:

示例 5-6:创建 User 新实例,其使用了一些来自 user1 的值

fn main() {
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

let user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

let user2 = User {
    email: String::from("another@example.com"),
    username: String::from("anotherusername567"),
    active: user1.active,
    sign_in_count: user1.sign_in_count,
};
}

简化写法:
如示例 5-7 所示。.. 语法指定了剩余未显式设置值的字段应有与给定实例对应字段相同的值。

fn main() {
struct User {
    username: String,
    email: String,
    sign_in_count: u64,
    active: bool,
}

let user1 = User {
    email: String::from("someone@example.com"),
    username: String::from("someusername123"),
    active: true,
    sign_in_count: 1,
};

let user2 = User {
    email: String::from("another@example.com"),
    username: String::from("anotherusername567"),
    ..user1
};
}

元组结构体(tuple structs)。元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。

定义元组结构体,以 struct 关键字和结构体名开头并后跟元组中的类型。例如,下面是两个分别叫做 Color 和 Point 元组结构体的定义和用法:

fn main() {
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}

注意 black 和 origin 值的类型不同,因为它们是不同的元组结构体的实例。你定义的每一个结构体有其自己的类型,即使结构体中的字段有着相同的类型。

结构体数据的所有权

上一篇 下一篇

猜你喜欢

热点阅读