15、16、17 章完结
This commit is contained in:
@@ -30,6 +30,54 @@ struct PhantomStruct<A, B> {
|
||||
// 注意:代码编译的时候只会为正常的泛型 `A` 申请空间,而幽灵类型 `B` 没有空间,
|
||||
// 所以使用了幽灵类型 `B` 的字段或者位置都不能当做实际存在的类型使用。
|
||||
|
||||
// 幽灵小测试
|
||||
fn testcase_unit_clarification() {
|
||||
// use std::marker::PhantomData;
|
||||
use std::ops::Add;
|
||||
|
||||
/// 创建两个枚举类型
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Inch {}
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Mm {}
|
||||
|
||||
/// `Length` 是一个拥有幽灵泛型 `Unit` 的一个元组结构,
|
||||
/// 我们明确指定了元组拥有一个 `f64` 的实际类型,
|
||||
/// f64 天然实现了 `Clone` 和 `Copy` 特性。
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct Length<Unit>(f64, PhantomData<Unit>);
|
||||
|
||||
/// `Add` 特性会重定义 `Length<Unit>` 这个类型的 `+` 操作符。
|
||||
impl<Unit> Add for Length<Unit> {
|
||||
type Output = Length<Unit>;
|
||||
|
||||
// add() 返回一个新的 `Length` 结构保存着加法的结果。
|
||||
fn add(self, rhs: Length<Unit>) -> Length<Unit> {
|
||||
// 实现 `+` 号的操作。
|
||||
Length(self.0 + rhs.0, PhantomData)
|
||||
}
|
||||
}
|
||||
|
||||
// 明确指明幽灵类型的实际类型是 `Inch`。
|
||||
let one_foot: Length<Inch> = Length(12.0, PhantomData);
|
||||
// 明确指明幽灵类型的实际类型是 `Mm`。
|
||||
let one_meter: Length<Mm> = Length(1000.0, PhantomData);
|
||||
|
||||
// 因为我们重定义了 `Length` 类型的 `+` 号操作符,所以这里可以直接使用 `+` 号进行计算,
|
||||
// 而 `Length` 类型实现了 `Copy` 特性,所以 `add()` 会优先使用 `Copy` 方法来复制一个副本进行所有权的转移,
|
||||
// 所以这里同一个变量使用两次才不会报错。
|
||||
let two_feet = one_foot + one_foot;
|
||||
let two_meters = one_meter + one_meter;
|
||||
|
||||
// 加法操作正常。
|
||||
println!("one foot + one_foot = {:?} in", two_feet.0);
|
||||
println!("one meter + one_meter = {:?} mm", two_meters.0);
|
||||
|
||||
// 没有意义的对比。
|
||||
// 编译错误: 类型不匹配
|
||||
// let one_feter = one_foot + one_meter;
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// 这里的 `f32` 和 `f64` 类型是给幽灵类型使用的。
|
||||
// PhantomTuple type specified as `<char, f32>`.
|
||||
@@ -55,4 +103,7 @@ fn main() {
|
||||
|
||||
// 编译错误!类型匹配不能对比
|
||||
// println!("_struct1 == _struct2 yields: {}", _struct1 == _struct2);
|
||||
|
||||
// 幽灵类型小测试
|
||||
testcase_unit_clarification();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user