Rust 从 0 到 1- 结构体 - 方法
结构体的方法与函数类似:都使用 fn 关键字声明,可以拥有参数和返回值,并且包含一段代码逻辑。不过与函数不同的是,它们在结构体的上下文中被定义(或者是 enum、trait 的上下文,在后续章节介绍),并且它的第一个参数是 self,它代表该方法对应的结构体实例。
定义方法
下面我们把前面计算矩形面积的 area 函数,改写成一个定义于 Rectangle 结构体上的方法:
与函数不同的是,在 area 方法的参数中,使用 &self 来替代 rectangle: &Rectangle,该方法位于结构体 Rectangle 上下文中,Rust 知道 self 的类型是 Rectangle。注意,self 前面的 & 和 &Rectangle 一样是对结构体的引用。这个和函数的参数一样,可以选择获取 self 的所有权,或者引用。如果想要在方法中改变实例,需要将第一个参数改为 &mut self。仅仅使用 self 作为第一个参数来使方法获取实例的所有权是很少使用的,通常用在当方法将 self 转换成别的实例,同时防止再调用方法后还使用原始的实例。
使用方法替代函数,除了可使用方法语法和不需要在每个函数参数中重复 self 的类型之外,其主要好处在于组织性。我们将某个类型实例能做的所有事情都一起放入 impl 中,而不是让用户在我们的库中到处寻找 Rectangle 的功能(这个感觉是借鉴了面向对象的思想)。
增加更多参数
下面通过实现 Rectangle 结构体上的另一方法来作为例子。这个方法(can_hold)实现以下逻辑:如果当前矩形能完全包含另一个矩形则返回 true;否则返回 false:
在方法参数中可以在 self (必须是第一个参数)后增加多个参数,就像函数中的参数一样。
关联函数
Rust 还可以在 impl 块中定义不以 self 作为参数的函数,称为关联函数(associated functions)。它们是函数而不是方法,它们不默认使用结构体的实例作为参数使用。譬如,String::from 就是一个关联函数。
关联函数经常被用作结构体的构造函数。例如,我们可以提供一个关联函数,它接受一个参数同时作为宽和高,从而可以更加方便的创建一个正方形 Rectangle ,而不必重复写两次相同的值:
如果要调用关联函数,可以使用 :: 语法(后面章节会详细介绍),比如:
多个 impl
每个结构体都允许拥有多个 impl 块:
多个 impl 是有效的语法,但似乎没什么必要。后面在讨论 generic types 和 trait 时会介绍多 impl 块的使用场景。
总结
结构体在 Rust 中体现了面向对象的思想和特性:让我们可以创建出有含义的自定义类型,将相关联的数据联系起来并给与有意义的命名;而方法则允许为结构体实例实现特有的行为,关联函数则将和结构体相关的功能置于结构体的命名空间中。
结构体并不是创建自定义类型的唯一方法,下面将介绍 Rust 的枚举类型。
版权声明: 本文为 InfoQ 作者【山】的原创文章。
原文链接:【http://xie.infoq.cn/article/9c5fb07e29765a88346bef4c3】。文章转载请联系作者。
评论