戴夫·赫尔曼(Dave Herman)最近在Rust的演讲中说,他们从C ++借用了此属性。我找不到关于该主题的任何内容。有人可以解释一下单质化的含义吗?
戴夫·赫尔曼(Dave Herman)最近在Rust的演讲中说,他们从C ++借用了此属性。我找不到关于该主题的任何内容。有人可以解释一下单质化的含义吗?
Answers:
单一化意味着生成通用功能的专用版本。如果我编写了一个提取任何一对第一个元素的函数:
fn first<A, B>(pair: (A, B)) -> A {
let (a, b) = pair;
return a;
}
然后我两次调用此函数:
first((1, 2));
first(("a", "b"));
编译器将生成的两个版本first()
,一个版本专用于整数对,另一个版本专用于字符串对。
该名称源自编程语言术语“多态性”,即一种可以处理多种类型数据的功能。单态化是从多态代码到单态代码的转换。
不确定是否有人还在看这个,但是Rust文档实际上确实提到了它如何通过此过程实现了成本抽象。从使用泛型的代码性能开始:
您可能想知道在使用泛型类型参数时是否存在运行时成本。好消息是,Rust以这样的方式实现泛型,即使用泛型类型的代码不会比使用具体类型的代码运行慢。
Rust通过在编译时对使用泛型的代码进行单态化来实现这一点。单色化是通过填充编译时使用的具体类型,将通用代码转换为特定代码的过程。
在此过程中,编译器执行与清单10-5中用于创建泛型函数的步骤相反的操作:编译器查看调用泛型代码的所有位置,并为调用泛型代码的具体类型生成代码。 。
让我们看看使用标准库的Option枚举的示例如何工作:
let integer = Some(5); let float = Some(5.0);
当Rust编译此代码时,它将执行单态化。在该过程中,编译器读取Option实例中已使用的值,并标识两种Option:一种是i32,另一种是f64。这样,它将Option的通用定义扩展为Option_i32和Option_f64,从而用特定的替换通用定义。
该代码的单色版本如下所示。通用Option替换为编译器创建的特定定义:
// Filename: src/main.rs enum Option_i32 { Some(i32), None, } enum Option_f64 { Some(f64), None, } fn main() { let integer = Option_i32::Some(5); let float = Option_f64::Some(5.0); }
因为Rust将通用代码编译成在每个实例中指定类型的代码,所以我们无需为使用通用而付出任何运行时成本。代码运行时,其性能与我们手工复制每个定义时的性能相同。单态化的过程使Rust的泛型在运行时非常高效。
Rust书中有一个很好的关于单态化的解释
单色化是通过填充编译时使用的具体类型,将通用代码转换为特定代码的过程。
在书籍示例中,如果您使用定义了变量Some
:
let integer = Some(5); let float = Some(5.0);
当Rust编译此代码时,它将执行单态化。在该过程中,编译器读取
Option<T>
实例中使用的值,并标识两种Option<T>
:一种是i32
,另一种是f64
。因此,其膨胀的一般定义Option<T>
成Option_i32
和Option_f64
,从而与特定的人代替通用定义。该代码的单色版本如下所示。泛型
Option<T>
被编译器创建的特定定义替换:文件名:src / main.rs
enum Option_i32 { Some(i32), None, } enum Option_f64 { Some(f64), None, } fn main() { let integer = Option_i32::Some(5); let float = Option_f64::Some(5.0); }