结构体(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