Skip to main content
Log in

Mojo struct

Variant

A runtime-variant type.

Data for this type is stored internally. Currently, its size is the largest size of any of its variants plus a 16-bit discriminant.

You can - use isa[T]() to check what type a variant is - use unsafe_take[T]() to take a value from the variant - use [T] to get a value out of a variant - This currently does an extra copy/move until we have lifetimes - It also temporarily requires the value to be mutable - use set[T](owned new_value: T) to reset the variant to a new value

Example:

from utils import Variant
alias IntOrString = Variant[Int, String]
fn to_string(inout x: IntOrString) -> String:
if x.isa[String]():
return x[String][]
# x.isa[Int]()
return str(x[Int][])

# They have to be mutable for now, and implement CollectionElement
var an_int = IntOrString(4)
var a_string = IntOrString(String("I'm a string!"))
var who_knows = IntOrString(0)
import random
if random.random_ui64(0, 1):
who_knows.set[String]("I'm actually a string too!")

print(to_string(an_int))
print(to_string(a_string))
print(to_string(who_knows))
from utils import Variant
alias IntOrString = Variant[Int, String]
fn to_string(inout x: IntOrString) -> String:
if x.isa[String]():
return x[String][]
# x.isa[Int]()
return str(x[Int][])

# They have to be mutable for now, and implement CollectionElement
var an_int = IntOrString(4)
var a_string = IntOrString(String("I'm a string!"))
var who_knows = IntOrString(0)
import random
if random.random_ui64(0, 1):
who_knows.set[String]("I'm actually a string too!")

print(to_string(an_int))
print(to_string(a_string))
print(to_string(who_knows))

Parameters

  • *Ts (CollectionElement): The elements of the variadic.

Implemented traits

AnyType, CollectionElement, Copyable, ExplicitlyCopyable, Movable

Methods

__init__

__init__(inout self: Self, *, unsafe_uninitialized: Tuple[])

Unsafely create an uninitialized Variant.

Args:

  • unsafe_uninitialized (Tuple[]): Marker argument indicating this initializer is unsafe.

__init__[T: CollectionElement](inout self: Self, owned value: T)

Create a variant with one of the types.

Parameters:

  • T (CollectionElement): The type to initialize the variant to. Generally this should be able to be inferred from the call type, eg. Variant[Int, String](4).

Args:

  • value (T): The value to initialize the variant with.

__init__(inout self: Self, *, other: Self)

Explicitly creates a deep copy of an existing variant.

Args:

  • other (Self): The value to copy from.

__copyinit__

__copyinit__(inout self: Self, other: Self)

Creates a deep copy of an existing variant.

Args:

  • other (Self): The variant to copy from.

__moveinit__

__moveinit__(inout self: Self, owned other: Self)

Move initializer for the variant.

Args:

  • other (Self): The variant to move.

__del__

__del__(owned self: Self)

Destroy the variant.

__getitem__

__getitem__[T: CollectionElement](ref [self_is_lifetime] self: Self) -> ref [_] $0

Get the value out of the variant as a type-checked type.

This explicitly check that your value is of that type! If you haven't verified the type correctness at runtime, the program will abort!

For now this has the limitations that it - requires the variant value to be mutable

Parameters:

  • T (CollectionElement): The type of the value to get out.

Returns:

The internal data represented as a Reference[T].

take

take[T: CollectionElement](inout self: Self) -> $0

Take the current value of the variant with the provided type.

The caller takes ownership of the underlying value.

This explicitly check that your value is of that type! If you haven't verified the type correctness at runtime, the program will abort!

Parameters:

  • T (CollectionElement): The type to take out.

Returns:

The underlying data to be taken out as an owned value.

unsafe_take

unsafe_take[T: CollectionElement](inout self: Self) -> $0

Unsafely take the current value of the variant with the provided type.

The caller takes ownership of the underlying value.

This doesn't explicitly check that your value is of that type! If you haven't verified the type correctness at runtime, you'll get a type that looks like your type, but has potentially unsafe and garbage member data.

Parameters:

  • T (CollectionElement): The type to take out.

Returns:

The underlying data to be taken out as an owned value.

replace

replace[Tin: CollectionElement, Tout: CollectionElement](inout self: Self, owned value: Tin) -> $1

Replace the current value of the variant with the provided type.

The caller takes ownership of the underlying value.

This explicitly check that your value is of that type! If you haven't verified the type correctness at runtime, the program will abort!

Parameters:

  • Tin (CollectionElement): The type to put in.
  • Tout (CollectionElement): The type to take out.

Args:

  • value (Tin): The value to put in.

Returns:

The underlying data to be taken out as an owned value.

unsafe_replace

unsafe_replace[Tin: CollectionElement, Tout: CollectionElement](inout self: Self, owned value: Tin) -> $1

Unsafely replace the current value of the variant with the provided type.

The caller takes ownership of the underlying value.

This doesn't explicitly check that your value is of that type! If you haven't verified the type correctness at runtime, you'll get a type that looks like your type, but has potentially unsafe and garbage member data.

Parameters:

  • Tin (CollectionElement): The type to put in.
  • Tout (CollectionElement): The type to take out.

Args:

  • value (Tin): The value to put in.

Returns:

The underlying data to be taken out as an owned value.

set

set[T: CollectionElement](inout self: Self, owned value: T)

Set the variant value.

This will call the destructor on the old value, and update the variant's internal type and data to the new value.

Parameters:

  • T (CollectionElement): The new variant type. Must be one of the Variant's type arguments.

Args:

  • value (T): The new value to set the variant to.

isa

isa[T: CollectionElement](self: Self) -> Bool

Check if the variant contains the required type.

Parameters:

  • T (CollectionElement): The type to check.

Returns:

True if the variant contains the requested type.

unsafe_get

unsafe_get[T: CollectionElement](ref [self_is_lifetime] self: Self) -> Reference[$1, $0, $2, 0]

Get the value out of the variant as a type-checked type.

This doesn't explicitly check that your value is of that type! If you haven't verified the type correctness at runtime, you'll get a type that looks like your type, but has potentially unsafe and garbage member data.

For now this has the limitations that it - requires the variant value to be mutable

Parameters:

  • T (CollectionElement): The type of the value to get out.

Returns:

The internal data represented as a Reference[T].

Was this page helpful?