Mojo struct
VariadicPack
@register_passable
struct VariadicPack[elt_is_mutable: Bool, //, is_owned: Bool, origin: Origin[elt_is_mutable], element_trait: AnyTrait[AnyType], *element_types: element_trait]
A utility class to access heterogeneous variadic function arguments.
VariadicPack
is used when you need to accept variadic arguments where each
argument can have a different type, but all types conform to a common trait.
Unlike VariadicList
(which is homogeneous), VariadicPack
allows each
element to have a different concrete type.
VariadicPack
is essentially a heterogeneous tuple that gets lowered to a
struct at runtime. Because VariadicPack
is a heterogeneous tuple (not an
array), each element can have a different size and memory layout, which
means the compiler needs to know the exact type of each element at compile
time to generate the correct memory layout and access code.
Therefore, indexing into VariadicPack
requires compile-time indices using
@parameter for
loops, whereas indexing into VariadicList
uses runtime
indices.
For example, in the following function signature, *args: *ArgTypes
creates a
VariadicPack
because it uses a variadic type parameter *ArgTypes
instead
of a single type. The *
before ArgTypes
indicates that ArgTypes
is a
variadic type parameter, which means that the function can accept any number
of arguments, and each argument can have a different type. This allows each
argument to have a different type while all types must conform to the
Intable
trait.
fn count_many_things[*ArgTypes: Intable](*args: *ArgTypes) -> Int:
var total = 0
# Must use @parameter for loop because args is a VariadicPack
@parameter
for i in range(args.__len__()):
# Each args[i] has a different concrete type from *ArgTypes
# The compiler generates specific code for each iteration
total += Int(args[i])
return total
def main():
print(count_many_things(5, 11.7, 12)) # Prints: 28
fn count_many_things[*ArgTypes: Intable](*args: *ArgTypes) -> Int:
var total = 0
# Must use @parameter for loop because args is a VariadicPack
@parameter
for i in range(args.__len__()):
# Each args[i] has a different concrete type from *ArgTypes
# The compiler generates specific code for each iteration
total += Int(args[i])
return total
def main():
print(count_many_things(5, 11.7, 12)) # Prints: 28
Parameters
- elt_is_mutable (
Bool
): True if the elements of the list are mutable for an mut or owned argument pack. - is_owned (
Bool
): Whether the elements are owned by the pack. If so, the pack will release the elements when it is destroyed. - origin (
Origin[elt_is_mutable]
): The origin of the underlying elements. - element_trait (
AnyTrait[AnyType]
): The trait that each element of the pack conforms to. - *element_types (
element_trait
): The list of types held by the argument pack.
Implemented traits
AnyType
,
Sized
,
UnknownDestructibility
Methods
__del__
__del__(var self)
Destructor that releases elements if owned.
__getitem__
__getitem__[index: Int](self) -> ref [origin] element_types[index.value]
Return a reference to an element of the pack.
Parameters:
- index (
Int
): The element of the pack to return.
Returns:
A reference to the element. The Pointer's mutability follows the mutability of the pack argument convention.
__len__
static __len__() -> Int
Return the VariadicPack length.
Returns:
The number of elements in the variadic pack.
__len__(self) -> Int
Return the VariadicPack length.
Returns:
The number of elements in the variadic pack.
Was this page helpful?
Thank you! We'll create more content like this.
Thank you for helping us improve!