Rust学习总结之结构体(一)

一:结构体定义

定义结构体,需要使用 struct 关键字并为整个结构体提供一个名字。结构体的名字需要描述它所组合的数据的意义。接着,在大括号中,定义每一部分数据的名字和类型,我们称为 字段field

rust 复制代码
struct User {
    active: bool,
    username: String,
    email: String,
    sign_in_count: u64,
}

二:结构体实例化

1,常规结构体赋值

下面创建一个结构体实例,并初始化以及给结构体字段赋值

rust 复制代码
fn main() {
    let mut user1 = User {
        email: String::from("[email protected]"),
        username: String::from("someusername123"),
        active: true,
        sign_in_count: 1,
    };

    user1.email = String::from("[email protected]");
}

注意整个实例必须是可变的;Rust 并不允许只将某个字段标记为可变。另外需要注意同其他任何表达式一样,我们可以在函数体的最后一个表达式中构造一个结构体的新实例,来隐式地返回这个实例

rust 复制代码
fn build_user(email: String, username: String) -> User {
    User {
        email: email,
        username: username,
        active: true,
        sign_in_count: 1,
    }
}

2,结构体字段初始化简写语法

上面的函数里面结构体初始化有更简便的写法,参数名与字段名都完全相同,我们可以使用字段初始化的简写语法

rust 复制代码
fn build_user(email: String, username: String) -> User {
    User {
        email,
        username,
        active: true,
        sign_in_count: 1,
    }
}

这里我们创建了一个新的 User 结构体实例,它有一个叫做 email 的字段。我们想要将 email 字段的值设置为 build_user 函数 email 参数的值。因为 email 字段与 email 参数有着相同的名称,则只需编写 email 而不是 email: email

3,结构体更新语法

使用旧实例的大部分值但改变其部分值来创建一个新的结构体实例通常很有用。这可以通过结构体更新语法struct update syntax)实现。

rust 复制代码
fn main() {
    // --snip--

    let user2 = User {
        active: user1.active,
        username: user1.username,
        email: String::from("[email protected]"),
        sign_in_count: user1.sign_in_count,
    };
}

上面例子中user2只有一个字段与user1不同,其他的字段可以用user1来赋值,这样在字段少的情况下还可以,但是如果字段多,这样也很繁琐,Rust有更简单的赋值方式

rust 复制代码
fn main() {
    // --snip--

    let user2 = User {
        email: String::from("[email protected]"),
        ..user1
    };
}

创建了一个新实例 user2,该实例具有不同的 email 值,但 usernameactivesign_in_count 字段的值与 user1 相同。..user1 必须放在最后,以指定其余的字段应从 user1 的相应字段中获取其值,但我们可以选择以任何顺序为任意字段指定值,而不用考虑结构体定义中字段的顺序。

在创建 user2 后不能再使用 user1,因为 user1username 字段中的 String 被移到 user2 中。如果我们给 user2emailusername 都赋予新的 String 值,从而只使用 user1activesign_in_count 值,那么 user1 在创建 user2 后仍然有效。activesign_in_count 的类型是实现 Copy trait 的类型

4,元组结构体

元组结构体有着结构体名称提供的含义,但没有具体的字段名,只有字段的类型。当你想给整个元组取一个名字,并使元组成为与其他元组不同的类型时,元组结构体是很有用的,这时像常规结构体那样为每个字段命名就显得多余和形式化了。

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

rust 复制代码
struct Color(i32, i32, i32);
struct Point(i32, i32, i32);

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

注意 blackorigin 值的类型不同,因为它们是不同的元组结构体的实例。你定义的每一个结构体有其自己的类型,即使结构体中的字段有着相同的类型。例如,一个获取 Color 类型参数的函数不能接受 Point 作为参数,即便这两个类型都由三个 i32 值组成。在其他方面,元组结构体实例类似于元组:可以将其解构为单独的部分,也可以使用 . 后跟索引来访问单独的值,等等。

相关推荐
勇敢牛牛_2 小时前
【Rust基础】crossbeam带来的阻塞问题
开发语言·笔记·rust
Hello.Reader14 小时前
在 Web 中调试 Rust-Generated WebAssembly
前端·rust·wasm
疏狂难除15 小时前
Windows安装Rust版本GDAL
rust·gdal
讲究事17 小时前
Built-in functions
rust·gpu
苏近之17 小时前
我用 Rust 写了一个 Hello World
rust
Linux编程用C1 天前
rust编程学习(二):复合数据类型
开发语言·学习·rust
ZC·Shou1 天前
Rust 之五 所有权、.. 和 _ 语法、引用和切片、Vec<T>、HashMap<K, V>
rust·集合·向量·引用·切片·所有权
YiSLWLL1 天前
Tauri 2.3.1+Leptos 0.7.8开发桌面应用--Sqlite数据库的写入、展示和选择删除
数据库·vscode·rust·sqlite·sqlx
pumpkin845141 天前
学习笔记十三—— 理解 Rust 闭包:从语法到 impl Fn vs Box<dyn Fn>
笔记·学习·rust
一只小松许️1 天前
Rust泛型与特性
java·开发语言·rust