结构体(Struct)
我们需要为每个工单追踪三部分信息:
- 标题
- 描述
- 状态
我们可以先使用 String 来表示它们。String是Rust标准库中定义的类型,用于表示UTF-8编码的文本。
但是,我们如何将这三部分信息合并为一个实体呢?
定义一个struct
struct定义了一个新的Rust类型。
#![allow(unused)] fn main() { struct Ticket { title: String, description: String, status: String, } }
struct与你在其他编程语言中称为类或对象的东西非常相似。
定义字段
新类型是通过组合其他类型作为字段建立的。
每个字段都需要一个名字和一个类型,中间用冒号分隔开::如果有多个字段,则用逗号,分隔开。
字段不必是同一类型,如下面的Configuration结构体所示:
#![allow(unused)] fn main() { struct Configuration { version: u32, active: bool, } }
实例化
通过为每个字段指定值可以创建一个struct的实例:
#![allow(unused)] fn main() { // 语法:<StructName> { <field_name>: <value>, ... } let ticket = Ticket { title: "建立一个工单系统".into(), description: "创建一个可以在看板上管理工单的系统".into(), status: "打开".into()}; }
访问字段
你可以使用.操作符访问struct的字段:
#![allow(unused)] fn main() { // 字段访问 let x = ticket.description; }
方法
我们可以通过定义方法为我们的struct附加行为。
以Ticket结构体为例:
#![allow(unused)] fn main() { impl Ticket { fn is_open(&self) -> bool { self.status == "Open" } } // 语法: // impl <StructName> { // fn <method_name>(&self, <parameters>) -> <return_type> { // // 方法体 // } // } }
方法与函数很相似,但有两个关键区别:
- 方法必须在**
impl块内定义 - 方法可以使用
self作为它们的第一个参数。self是一个关键字,代表调用其调用方法的struct实例。
self
如果方法以self作为其第一个参数,它可以使用方法调用语法调用:
#![allow(unused)] fn main() { // 方法调用语法: <instance>.<method_name>(<parameters>) let is_open = ticket.is_open(); }
这与上一章中对u32值执行饱和算术操作使用的调用语法相同02_basic_calculator/09_saturating.md。
静态方法
如果方法不以self作为其第一个参数,它是一个静态方法。
#![allow(unused)] fn main() { struct Configuration { version: u32, active: bool, } impl Configuration { // `default` 是 `Configuration` 上的静态方法 fn default() -> Configuration { Configuration { version: 0, active: false } } }
调用静态方法的唯一方式是使用函数调用语法:
#![allow(unused)] fn main() { // 函数调用语法: <StructName>::<method_name>(<parameters>) let default_config = Configuration::default(); }
等价性
即使以self作为第一个参数的方法,你也可以使用函数调用语法:
#![allow(unused)] fn main() { // 函数调用语法: <StructName>::<method_name>(<instance>, <parameters>) let is_open = Ticket::is_open(ticket); }
函数调用语法清晰地表明ticket作为self,方法的第一个参数在使用,但确实更冗长。可能时优先使用方法调用语法。
参考资料
- 本节练习位于
exercises/03_ticket_v1/01_struct