函数
在先前的代码中, 我们定义了 todos 变量来存储 Todo 项, 并逐个实例化 Todo 项然后添加到 todos 中。
我们实例化 Todo 项的代码如下, 可以看到, 有些繁琐:
TodoItem {
title: "learn rust".to_string(),
content: "read rust book".to_string(),
}
为了避免每次都写重复的转换和构造过程, 我们可以使用 Rust 的函数。
函数是一段可以被重复调用的代码块。用于完成特定的任务。可以:
- 将某段功能独立出, 从而进行复用, 避免代码重复。
- 通过函数名描述功能, 让代码结构清晰, 提升可读性。
- 需要修改则只需要修改函数内部, 并不会影响外部调用, 增加了维护性和扩展性。
- 通过传递不同参数, 来改变函数内部走向, 实现不同的功能。
- 可以返回值, 实现外部与内部交互。
fn create_todo_item(title: &str, content: &str) -> TodoItem {
return TodoItem {
title: title.to_string(),
content: content.to_string(),
};
}
fn main() {
let mut todos: Vec<TodoItem> = Vec::new();
todos.push(create_todo_item("learn rust", "read rust book"));
todos.push(create_todo_item("work", "complete required"));
todos.push(create_todo_item("play", "play game"));
// ...
}
在以上示例中, create_todo_item 接受两个 &str 类型的参数。返回 TodoItem 类型。
在它内部, 实现了将两个 &str 参数转换为 String 类型的值, 并绑定到 TodoItem 类型的实例上。
随后, 我们只需要使用 create_todo_item("title", "content"); 就可以实例化一个 TodoItem 类型了。
相较于先前需要手动指定结构体类型、列出所有字段并逐一进行字符串转换的写法, 使用函数可以大大减少重复代码, 提升开发效率。
通过封装 create_todo_item 函数, 我们只需要传入标题和内容两个参数, 就能快速创建一个 TodoItem 实例, 既简洁, 又易于阅读和维护。
这样的封装方式在实际开发中非常常见, 也体现了函数抽象的核心思想: 隐藏实现细节, 对外暴露清晰的接口。
函数返回值
在 create_todo_item 中, 我们使用了 return 关键字返回了一个 TodoItem 类型的实例。
但是实际上, 我们其实可以不使用 return 关键字, 将函数改为:
fn create_todo_item(title: &str, content: &str) -> TodoItem {
TodoItem {
title: title.to_string(),
content: content.to_string(),
}
}
将行尾的 ; 分号去掉, 就可以返回数据了。这是因为 Rust 默认将函数体中最后一个表达式的值作为返回值。
我们将行尾的 ; 分号去掉了, 就将语句改为了表达式, 于是 Rust 可以将这个表达式的值作为返回值。
如果需要提前返回,才需要使用 return 关键字。
元组
元组是多种类型组合在一起形成的复合类型。长度和顺序都是固定的。 我们可以简单的将元组视为一个不能改变类型顺序的数组。
let tup: (i32, f64, &str) = (1, 1.0, "1");
元组允许使用 . 访问内容。
let a = tup.0
let b = tup.1
let c = tup.2
常用于包装多个值并供给其他地方使用。
单元类型
Rust 的单元类型只有一个值, 即 ()。
它实际上是一个特殊元组, 但需要注意的是, Rust 中元组一定不能为空, 为空就不是元组了。
通常, 单元类型被用来表示无返回值。
没有返回值的函数实际上相当于默认返回了一个空元组 ()。