Rust中可允许自定义的类型仅有两种: 结构体 和 枚举 。其中枚举用于特定场景,而结构体被设计用来支持广泛场景。
Rust的结构体不支持继承,所以虽然struct和trait的组合看起来像但其实不是通常意义(C++/Java)上的面向对象实践。不过trait支持默认方法,可以部分填补该差别。
声明结构体
基本的结构体声明和C语言很类似:
struct Point { x: i32, y: i32, }
值得一提的是,Rust的结构体的可变性是一个整体,也就是说无法对某一个域单独声明可变性。
若结构体某成员是引用,其寿元需要在声明结构体时一起声明:
struct Product<'a> { value: i32, price: i32, name: &'a String, }
结构体也支持泛型:
struct Point<T> { a: T, b: T, }
构造一个结构体的语法也很直观:
Point { x: 0, y: 0 }
由于Rust编译器会自动尝试进行类型和寿元的推导,不需要在构造时显式声明类型和寿元。注意Rust没有构造函数 / 构造器(见下一节)。
方法定义
和Java等语言不同,Rust的方法定义需要单独列出:
struct Point { x: i32, y: i32, } impl Point { fn origin() -> Self { Point { x: 0, y: 0 } } fn move_x(mut self, d: i32) { self.x += d; } }
例子中定义了一个 origin()
函数和一个 move_x()
函数。我们也可以叫 move_x()
为方法,因为其首个参数为 self
,代指当前「对象」(结构体实例)。下一小节专门介绍 self
参数。
origin()
函数类似于静态方法,其调用方式为 Point::origin()
。其返回值类型为 Self
,代表当前结构体类型,省去了手动输入的麻烦。该语法在下面涉及 trait
时尤为有用。
前面说到,Rust中没有构造函数,因为结构体不是类`。但习惯上,多数结构体会提供一个 new() -> Self
函数,充当构造函数。
方法的 self
参数
第一个参数为 self
的结构体函数叫做方法,其可以是 self
mut self
&self
&mut self
中的任何一种,代表不同语义。
首先,无论何种形式,该 self
均指当前实例;mut
表示可变性,调用者需要满足。
self
和 mut self
表示该方法调用者是值,并且由于是值所以值会移动进方法中;&self
和 &mut self
表示该方法调用者是引用,而引用则不用在意移动之事。
移动与否一事影响很大,所以在选择该方案前要慎重。通常见到的多是引用形式的,此时只用考虑可变性一件事。对于方法调用特殊的一点是,Rust会自动尝试从 self
向 &self
进行转换。
选择引用形式的self
的效果类似于C++中的const
成员函数,也类似golang中是否选择*
。
未完待续...
您可以在Hypothesis上的該群組內進行評論,或使用下面的Disqus評論。