Skip to main content

Mojo struct

Reflected

struct Reflected[T: AnyType]

A compile-time reflection handle for a type.

Reflected[T] is a zero-sized handle that exposes compile-time introspection of T through methods. Construct it via reflect[T]().

For best performance, assign the result of reflect[T]() and any methods that return type-level values (such as field_names, field_types, field_count) to comptime variables so the work happens at compile time.

Example:

from std.reflection import reflect

struct Point:
    var x: Int
    var y: Float64

def main():
    comptime r = reflect[Point]()
    comptime if r.is_struct():
        comptime names = r.field_names()
        comptime for i in range(r.field_count()):
            print(names[i])

Parameters

  • T (AnyType): The type being introspected. The wrapped type is exposed via this parameter, so reflect[T]().T is T.

Implemented traits

AnyType, Copyable, ImplicitlyCopyable, ImplicitlyDestructible, Movable, RegisterPassable, TrivialRegisterPassable

Methods

__init__

__init__() -> Self

Constructs a reflection handle. Prefer reflect[T]().

is_struct

is_struct(self) -> Bool

Returns True if T is a Mojo struct type, False otherwise.

This distinguishes Mojo struct types from MLIR primitive types (such as __mlir_type.index or __mlir_type.i64). The other reflection methods produce a compile error on non-struct types, so is_struct is useful as a comptime if guard when iterating over field types that may contain MLIR primitives.

Example:

from std.reflection import reflect, get_type_name

def process_type[T: AnyType]():
    comptime r = reflect[T]()
    comptime if r.is_struct():
        print("struct with", r.field_count(), "fields")
    else:
        print("non-struct:", get_type_name[T]())

Returns:

Bool: True if T is a Mojo struct type, False if it is an MLIR type.

field_count

field_count(self) -> Int

Returns the number of fields in struct T.

Constraints:

T must be a struct type.

Returns:

Int: The number of fields in the struct.

field_types

field_types(self) -> TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>]

Returns the types of all fields in struct T as a TypeList.

For nested structs this returns the struct type itself, not its flattened fields.

Example:

from std.reflection import reflect, get_type_name

struct Point:
    var x: Int
    var y: Float64

def main():
    comptime r = reflect[Point]()
    comptime types = r.field_types()
    comptime for i in range(r.field_count()):
        print(get_type_name[types[i]]())

Constraints:

T must be a struct type.

Returns:

TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>]: A TypeList with one entry per field in the struct.

field_names

field_names(self) -> InlineArray[StringSlice[StaticConstantOrigin], TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>].size]

Returns the names of all fields in struct T.

Constraints:

T must be a struct type.

Returns:

InlineArray[StringSlice[StaticConstantOrigin], TypeList[#kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>].size]: An InlineArray of StaticString, one entry per field.

field_index

field_index[name: StringLiteral[name.value]](self) -> Int

Returns the index of the field with the given name in struct T.

Note: T must be a concrete type, not a generic type parameter, when looking up by name.

Parameters:

Returns:

Int: The zero-based index of the field.

field_type

field_type[name: StringLiteral[name.value]](self) -> Reflected[#kgen.struct_field_type_by_name<:trait<_std::_builtin::_anytype::_AnyType> T, #kgen.param.decl.ref<"name.value`2x"> : !kgen.string>]

Returns a reflection handle for the type of the named field.

The returned handle's T parameter is the field's type, so r.field_type["x"]().T can be used in type position.

Note: T must be a concrete type, not a generic type parameter, when looking up by name.

Example:

from std.reflection import reflect

struct Point:
    var x: Int
    var y: Float64

def main():
    comptime r = reflect[Point]()
    comptime y_type = r.field_type["y"]()
    var v: y_type.T = 3.14  # y_type.T is Float64

Parameters:

Returns:

Reflected[#kgen.struct_field_type_by_name<:trait<_std::_builtin::_anytype::_AnyType> T, #kgen.param.decl.ref<"name.value`2x"> : !kgen.string>]: A Reflected handle whose T is the named field's type.

field_ref

field_ref[idx: Int](self, ref s: T) -> ref[s_is_mut] #kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>[idx]

Returns a reference to the field at the given index in s.

Returns a reference rather than a copy, so this works with non-copyable field types and supports mutation through the result.

Example:

from std.reflection import reflect

@fieldwise_init
struct Container:
    var id: Int
    var name: String

def main():
    var c = Container(id=1, name="test")
    comptime r = reflect[Container]()
    r.field_ref[0](c) = 42  # mutates c.id

Constraints:

T must be a struct type. idx must be in range [0, field_count()).

Parameters:

  • idx (Int): The zero-based index of the field.

Args:

  • s (T): The struct value to access.

Returns:

ref[s_is_mut] #kgen.struct_field_types<:trait<_std::_builtin::_anytype::_AnyType> T>[idx]: A reference to the field at the specified index, with the same mutability as s.

field_offset

field_offset[*, name: StringLiteral[name.value], target: __mlir_type.`!kgen.target` = _current_target()](self) -> Int

Returns the byte offset of the named field within struct T.

Accounts for alignment padding between fields. Computed using the target's data layout.

Example:

from std.reflection import reflect

struct Point:
    var x: Int      # offset 0
    var y: Float64  # offset 8

def main():
    comptime r = reflect[Point]()
    comptime x_off = r.field_offset[name="x"]()  # 0
    comptime y_off = r.field_offset[name="y"]()  # 8

Constraints:

T must be a struct type with a field of the given name.

Parameters:

  • name (StringLiteral[name.value]): The name of the field.
  • target (__mlir_type.`!kgen.target`): The target architecture (defaults to the current target).

Returns:

Int: The byte offset of the field from the start of the struct.

field_offset[*, index: Int, target: __mlir_type.`!kgen.target` = _current_target()](self) -> Int

Returns the byte offset of the field at the given index.

Accounts for alignment padding between fields. Computed using the target's data layout.

Constraints:

T must be a struct type. index must be in range [0, field_count()).

Parameters:

  • index (Int): The zero-based index of the field.
  • target (__mlir_type.`!kgen.target`): The target architecture (defaults to the current target).

Returns:

Int: The byte offset of the field from the start of the struct.

Was this page helpful?