struct_field_count[T]() - 返回结构体中的字段数
struct_field_names[T]() - 以 [StaticString, N] 形式的 InlineArray 返回字段名称
struct_field_types[T]() - 返回所有字段类型的可变参数列表
struct_field_index_by_name[T, name]() - 按名称返回字段索引
struct_field_type_by_name[T, name]() - 返回包装在 ReflectedType 中的字段类型
这些 API 适用于具体类型和泛型类型参数:
fn print_fields[T: AnyType]():
comptime names = struct_field_names[T]()
comptime types = struct_field_types[T]()
@parameter
for i in range(struct_field_count[T]()):
print(names[i], get_type_name[types[i]]())
按索引访问字段 - 两个新的神奇函数支持基于索引的字段访问而无需复制:
__struct_field_type_at_index(T, idx) - 返回索引处的字段类型
__struct_field_ref(idx, ref s) - 返回字段的引用
与复制数据的 kgen.struct.extract 不同,__struct_field_ref() 返回一个引用,使反射实用程序能够与非可复制类型一起工作:
fn print_all_fields[T: AnyType](ref s: T):
comptime names = struct_field_names[T]()
@parameter
for i in range(struct_field_count[T]()):
print(names[i], "=", __struct_field_ref(i, s))
字段字节偏移量 - offset_of[T, name=field_name]() 返回结构体内命名字段的字节偏移量,实现无需复制的序列化和其他低级内存操作。偏移量是使用目标的数据布局在编译时计算的,正确考虑了对齐填充。这类似于 C/C++ 的 offsetof 和 Rust 的 offset_of! 宏。还有一个 offset_of[T, index=i]() 重载可用于按字段索引查找。
from reflection import offset_of
struct Point:
var x: Int # 偏移量 0
var y: Float64 # 偏移量 8(对齐后)
fn main():
comptime x_off = offset_of[Point, name="x"]() # 0
comptime y_off = offset_of[Point, name="y"]() # 8
类型内省实用程序:
is_struct_type[T]() - 如果 T 是 Mojo 结构体类型则返回 True。对于保护使用结构体特定 API 的反射代码以避免非结构体类型(例如,MLIR 原始类型)上的编译器错误很有用。使用 @parameter if,因为这些 API 在编译时求值。
get_base_type_name[T]() - 返回参数化类型基类型的非限定名称。例如,get_base_type_name[List[Int]]() 返回 "List"。对于识别集合类型而不管其元素类型很有用。
源代码位置内省:
SourceLocation - 保存文件名、行号和列信息的结构体
source_location() - 返回其被调用位置
call_location() - 返回调用者被调用的位置(要求调用者是 @always_inline)
这些以前是 builtin._location 中的内部 API(_SourceLocation、__source_location、__call_location)。旧的模块已被移除。
from reflection import source_location, call_location, SourceLocation
fn main():
var loc = source_location()
print(loc) # main.mojo:5:15
@always_inline
fn log_here():
var caller_loc = call_location()
print("Called from:", caller_loc)
注意:这些 API 在参数表达式(编译时上下文)中无法正常工作(它们返回占位符值)。
特质一致性检查 - conforms_to() 内置函数现在接受来自 struct_field_types[T]() 等反射 API 的类型,从而能够对动态获取的字段类型进行一致性检查:
@parameter
for i in range(struct_field_count[MyStruct]()):
comptime field_type = struct_field_types[MyStruct]()[i]
@parameter
if conforms_to(field_type, Copyable):
print("Field", i, "is Copyable")