03 Methods¶
方法是与类型相关联的函数, 可以通过实例调用, 也可以通过类型调用(如果是静态方法). 在 YIAN 中, 任何类型都可以定义方法. 方法的定义使用 impl 块, 语法为:
impl<type_parameters> <type> {
<method_definition1>
<method_definition2>
...
<method_definitionN>
}
或者
impl<type_parameters> <trait> for <type> {
<method_definition1>
<method_definition2>
...
<method_definitionN>
}
<type_parameters>: 可选的类型参数列表, 用于定义泛型 impl 块, 泛型 impl 块可以为一个满足特定条件的类型族(而不是一个单一的类型)实现方法, 详见泛型章节<type>: 方法所属的类型<trait>: 方法所属的 trait, 只有在为 trait 实现方法时才需要指定<method_definition>: 方法的定义, 格式与函数定义相同, 包含方法体, 用花括号{ ... }包围- 方法前面可以有访问修饰符以及
static关键字 - 使用
impl <type> { ... }定义的方法称为 inherent method, 使用impl <trait> for <type> { ... }定义的方法称为 trait method
Inherent Method¶
Inherent method 是直接定义在类型上的方法, 实例:
现有自定义 struct Point:
struct Point {
f32 x
f32 y
}
下面为 Point 定义两个方法, 一个是实例方法 distance_from_origin, 另一个是静态方法 new:
impl Point {
// 实例方法, 计算点到原点的距离
pub f32 distance_from_origin() {
return (self.x * self.x + self.y * self.y).sqrt()
}
// 静态方法, 创建一个新的 Point 实例
pub static Point new(f32 x, f32 y) {
return Point(x, y)
}
}
distance_from_origin是一个实例方法, 通过self参数访问调用该方法的实例的字段, 可以通过point.distance_from_origin()来调用, 其中point是一个Point类型的实例new是一个静态方法, 没有self参数, 只能通过Point.new(x, y)来调用.
也可以为内置类型定义 inherent method:
impl f32 {
// 静态方法, 将角度转换为弧度
pub static f32 from_degrees(f32 degrees) {
return degrees * 3.141592653589793 / 180.0
}
// 实例方法, 计算一个数的根号
pub f32 sqrt() {
// 这里使用牛顿迭代法来计算平方根
f32 guess = self / 2.0
loop {
f32 next_guess = (guess + self / guess) / 2.0
if (next_guess - guess).abs() < 1e-6 {
break
}
guess = next_guess
}
return guess
}
}
from_degrees是一个静态方法, 用于将角度转换为弧度, 可以通过f32.from_degrees(degrees)来调用sqrt是一个实例方法, 用于计算一个f32数的平方根, 可以通过value.sqrt()来调用, 其中value是一个f32类型的实例
Trait Method¶
Trait method 的定义方式和调用方式和 inherent method 完全一致, 唯一的区别是 trait method 的签名必须与 trait 中声明的方法签名完全匹配, 包括方法名, 参数列表, 返回类型以及访问修饰符. 例如, 假设有一个 trait Drawable:
trait Drawable {
pub draw() {
// 默认实现, 可以被覆盖
}
}
下面为 Point 实现 Drawable trait:
impl Drawable for Point {
pub draw() {
// 在这里实现绘制 Point 的逻辑, 例如输出坐标
}
}
draw是Drawabletrait 中声明的方法, 在impl Drawable for Point块中为Point实现了这个方法