简介
在本实验中,我们将探讨虚类型参数(phantom type parameter)的概念,它是在编译时进行静态检查的类型参数,没有任何运行时行为或值。我们通过将 std::marker::PhantomData 与虚类型参数的概念相结合,在 Rust 中展示它们的用法,以创建包含不同数据类型的元组和结构体。
注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用
main.rs,并通过rustc main.rs &&./main进行编译和运行。
在本实验中,我们将探讨虚类型参数(phantom type parameter)的概念,它是在编译时进行静态检查的类型参数,没有任何运行时行为或值。我们通过将 std::marker::PhantomData 与虚类型参数的概念相结合,在 Rust 中展示它们的用法,以创建包含不同数据类型的元组和结构体。
注意:如果实验未指定文件名,你可以使用任何你想要的文件名。例如,你可以使用
main.rs,并通过rustc main.rs &&./main进行编译和运行。
虚类型参数是在运行时不会出现,但仅在编译时进行静态检查的参数。
数据类型可以使用额外的泛型类型参数来充当标记,或在编译时执行类型检查。这些额外的参数不持有存储值,也没有运行时行为。
在以下示例中,我们将 [std::marker::PhantomData] 与虚类型参数概念相结合,以创建包含不同数据类型的元组。
use std::marker::PhantomData;
// 一个虚元组结构体,它对 `A` 是泛型的,带有隐藏参数 `B`。
#[derive(PartialEq)] // 允许对这个类型进行相等性测试。
struct PhantomTuple<A, B>(A, PhantomData<B>);
// 一个虚类型结构体,它对 `A` 是泛型的,带有隐藏参数 `B`。
#[derive(PartialEq)] // 允许对这个类型进行相等性测试。
struct PhantomStruct<A, B> { first: A, phantom: PhantomData<B> }
// 注意:为泛型类型 `A` 分配了存储空间,但没有为 `B` 分配。
// 因此,`B` 不能用于计算。
fn main() {
// 这里,`f32` 和 `f64` 是隐藏参数。
// PhantomTuple 类型指定为 `<char, f32>`。
let _tuple1: PhantomTuple<char, f32> = PhantomTuple('Q', PhantomData);
// PhantomTuple 类型指定为 `<char, f64>`。
let _tuple2: PhantomTuple<char, f64> = PhantomTuple('Q', PhantomData);
// 类型指定为 `<char, f32>`。
let _struct1: PhantomStruct<char, f32> = PhantomStruct {
first: 'Q',
phantom: PhantomData,
};
// 类型指定为 `<char, f64>`。
let _struct2: PhantomStruct<char, f64> = PhantomStruct {
first: 'Q',
phantom: PhantomData,
};
// 编译时错误!类型不匹配,所以这些不能进行比较:
// println!("_tuple1 == _tuple2 yields: {}",
// _tuple1 == _tuple2);
// 编译时错误!类型不匹配,所以这些不能进行比较:
// println!("_struct1 == _struct2 yields: {}",
// _struct1 == _struct2);
}
恭喜你!你已经完成了虚类型参数实验。你可以在 LabEx 中练习更多实验来提升你的技能。