我正在查看Rust中一些基本类型背后的代码,例如Option<T>
的{{3}}或tuple
后面的pleasantly simple implementation,我能够在weird macro magic找到我想要的所有类型。除了一个之外的所有 - bool
。我无法在其他任何地方找到它。
Rust中bool
背后的代码在哪里?我知道这不是最新颖的类型,但我很惊讶我找不到它。
感谢Francis和rodrigo的回答,我注意到我为其他原语找到的代码只是它们的特征和相关的宏,而不是实际的实现。
Rust书中说明了原语libcore,但我对此解释并不满意。他们什么时候建成?它可以追溯到Rust编译器最初使用Rust构建的时候还是在它仍然在OCaml中构建时发生的?是否存在任何相关代码?
答案 0 :(得分:13)
所以这里有关于编译器中发生了什么的更多信息。对于初学者,正如已经提到的,布尔值发生的实际操作完全由LLVM处理,并直接转换为相应的CPU指令。虽然在某些情况下代码会因为自举而神奇地出现,但这不是其中之一。编译器专门用于处理这些类型并发出正确的LLVM指令。
对于编译的最早部分(例如在宏扩展期间),类型bool
并不特殊。它只是标识符bool
的一些路径。最终around here它将转换为基本类型。该类型的实际定义是here。
现在让我们来看看!
运算符的工作原理。正如我之前提到的,执行impl Not for bool
的libcore中的代码永远不会被使用。 !expr
形式的代码会转换为<T as Not>::not(expr)
here。但是,您会注意到它会检查此特定表达式是否实际上是一个方法调用,如果它不是一个方法调用,则将其保留为!expr
。怎么知道的? MIR中的调用只是缓存查找。在类型检查过程中填充了缓存。 Here是缓存插入的位置 - 基本上检查Not
特征是否在任何时候看到!
时都是针对给定类型实现的。你会注意到this line明确地排除了布尔值和整数类型,最终直接编译成LLVM指令。
这是如何定义的粗略画面。您可以在其他基元的相同文件中找到类似的代码。从理论上讲,某些行可能存在enum bool { true, false }
- 但最终这个相同的代码仍然需要覆盖它并发出适当的LLVM内在函数,并且整数不能用这种方式表示。
答案 1 :(得分:11)
bool
is a primitive type。它们上的原始类型和操作由编译器实现,即编译器发出专门的代码来对原始类型执行操作。
您会看到bool
实现了许多特征。这些实现来自libcore,但它们通常通过使用相应的运算符来实现。例如,Not::not
is implemented by returning !self
。对于任何非基本类型,这将递归调用Not::not
并导致堆栈溢出,但对于基本类型,编译器以不同方式解析运算符,并且这些特征实现仅为通用代码的优点提供。
答案 2 :(得分:3)
由于常量core::i32
和i32::MIN
,您只能看到i32::MAX
的定义。实际类型只是内置类型i32
的别名。
在core::f32
的情况下,例如有很多有用的常量。
但是对于bool
,除了true
和false
以外,没有有用的值是关键字,因此bool
没有来源。