> For the complete Mojo documentation index, see [llms.txt](/llms.txt).
> Markdown versions of all pages are available by appending .md to any URL (e.g. /docs/manual/basics.md).

# Value creation

The life of a value in Mojo begins when a variable is initialized and continues
up until the value is last used, at which point Mojo destroys it. This page
describes how every value in Mojo is created, copied, and moved. (The next
page describes [how values are
destroyed](/docs/manual/lifecycle/death).)

All data types in Mojo—including basic types in the standard library such as
[`Bool`](/docs/std/builtin/bool/Bool/), [`Int`](/docs/std/builtin/int/Int/),
and [`String`](/docs/std/collections/string/string/String/)—are defined as
[structs](/docs/manual/structs/). This means the creation and destruction of any
piece of data follows the same lifecycle rules, and you can define your own data
types that work exactly the same way.

Mojo structs don't get any default lifecycle methods, such as a
constructor, copy constructor, or move constructor. That means you can define
a struct without a constructor, but then you can't instantiate it, and it
would be useful only as a sort of namespace for static methods. For example:

```mojo
struct NoInstances:
    var state: Int

    @staticmethod
    def print_hello():
        print("Hello world!")
```

Without a constructor, this can't be instantiated, so it has no lifecycle. The
`state` field is also useless because it can't be initialized (Mojo structs do
not support default field values—you must initialize them in a constructor).

So the only thing you can do is call the static method:

```mojo
NoInstances.print_hello()
```

```output
Hello world!
```

## Constructor

To create an instance of a Mojo type, it needs the `__init__()` constructor
method. The main responsibility of the constructor is to initialize all fields.
For example:

```mojo
struct MyPet:
    var name: String
    var age: Int

    def __init__(out self, name: String, age: Int):
        self.name = name
        self.age = age
```

Now we can create an instance:

```mojo
var mine = MyPet("Loki", 4)
```

An instance of `MyPet` can also be read
and destroyed, but it currently can't be copied or moved.

We believe this is a good default starting point, because there are no built-in
lifecycle events and no surprise behaviors. You—the type author—must
explicitly decide whether and how the type can be copied or moved, by
implementing the copy and move constructors.

The pattern shown above—a constructor that takes an argument for each of the
struct's fields and initializes the fields directly from the arguments—is called
a *field-wise constructor*. It's a common enough pattern that Mojo includes a
[`@fieldwise_init`](/docs/reference/decorators/fieldwise-init/) decorator to
synthesize the field-wise constructor. So you can rewrite the previous example
like this:

```mojo
@fieldwise_init
struct MyPet:
    var name: String
    var age: Int
```

:::note

Mojo does not require a destructor to destroy an instance. But in some cases,
you may need to define a custom destructor to release resources (for example, if
a struct dynamically allocates memory using
[`UnsafePointer`](/docs/std/memory/unsafe_pointer/UnsafePointer/)). We'll
discuss that more in [Death of a value](/docs/manual/lifecycle/death/).

:::

:::note The "constructor" name

In a Python class, object construction happens across both the `__new__()` and
`__init__()` methods, so the `__init__()` method is technically just the
initializer for attributes (but it's often still called the constructor).
However, in a Mojo struct, there is no `__new__()` method, so we prefer to
always call `__init__()` the constructor.

:::

### Overloading the constructor

Like any other function/method, you can
[overload](/docs/manual/functions/#overloaded-functions) the
`__init__()` constructor to initialize the object with different arguments. For
example, you might want a default constructor that sets some default values and
takes no arguments, and then additional constructors that accept more arguments.

Just be aware that, in order to modify any fields, each constructor must
declare the `self` argument with the [`out`
convention](/docs/manual/values/ownership#argument-conventions). If you
want to call one constructor from another, you simply call upon that
constructor as you would externally (you don't need to pass `self`).

For example, here's how you can delegate work from an overloaded constructor:

```mojo
struct MyPet:
    var name: String
    var age: Int

    def __init__(out self):
        self.name = ""
        self.age = 0

    def __init__(out self, name: String):
        self = MyPet()
        self.name = name
```

### Field initialization

Notice in the previous example that, by the end of each constructor, all fields
must be initialized. That's the only requirement in the constructor.

In fact, the `__init__()` constructor is smart enough to treat the `self`
object as fully initialized even before the constructor is finished, as long
as all fields are initialized. For example, this constructor can pass around
`self` as soon as all fields are initialized:

```mojo
def use(arg: MyPet):
    pass

struct MyPet:
    var name: String
    var age: Int

    def __init__(out self, name: String, age: Int, cond: Bool):
        self.name = name
        if cond:
            self.age = age
            use(self)  # Safe to use immediately!

        self.age = age
        use(self)  # Safe to use immediately!
```

### Constructors and implicit conversion

Mojo supports implicit conversion from one type to another. Implicit conversion
can happen when one of the following occurs:

- You assign a value of one type to a variable with a different type.
- You pass a value of one type to a function that requires a different type.
- You return a value of one type from a function that specifies a different
  return type.

In all cases, implicit conversion is supported when the target type
defines a constructor that meets the following criteria:

- Is declared with the `@implicit` decorator.
- Has a single required, non-keyword argument of the source type.

For example:

```mojo
var a = Source()
var b: Target = a
```

Mojo implicitly converts the `Source` value in `a` to a `Target` value if
`Target` defines a matching constructor like this:

```mojo
struct Target:

    @implicit
    def __init__(out self, s: Source): ...
```

With implicit conversion, the assignment above is essentially identical to:

```mojo
var b = Target(a)
```

In general, types should only support implicit conversions when the conversion
is lossless and ideally inexpensive. For example, converting an integer to a
floating-point number is usually lossless (except for very large positive and
negative integers, where the conversion may be approximate), but converting a
floating-point number to an integer is very likely to lose information. So
Mojo supports implicit conversion from `Int` to `Float64`, but not the reverse.

The constructor used for implicit conversion can take optional arguments, so
the following constructor would also support implicit conversion from `Source`
to `Target`:

```mojo
struct Target:

    @implicit
    def __init__(out self, s: Source, reverse: Bool = False): ...
```

Implicit conversion can fail if Mojo can't unambiguously match the conversion to
a constructor. For example, if the target type has two overloaded constructors
that take different types, and each of those types supports an implicit
conversion from the source type, the compiler has two equally-valid paths to
convert the values:

```mojo
struct A:
    @implicit
    def __init__(out self, s: Source): ...

struct B:
    @implicit
    def __init__(out self, s: Source): ...

struct OverloadedTarget:
    @implicit
    def __init__(out self, a: A): ...
    @implicit
    def __init__(out self, b: B): ...

var t = OverloadedTarget(Source()) # Error: ambiguous call to '__init__': each
                                   # candidate requires 1 implicit conversion
```

In this case, you can fix the issue by explicitly casting to one of the
intermediate types. For example:

```mojo
var t = OverloadedTarget(A(Source())) # OK
```

Mojo applies at most one implicit conversion to a variable. For example:

```mojo
var t: OverloadedTarget = Source() # Error: can't implicitly convert Source
                                   # to Target
```

Would fail because there's no direct conversion from `Source` to
`OverloadedTarget`.

For structs with a single field, you can generate an implicit constructor with
the `@fieldwise_init("implicit")` decorator.

```mojo
@fieldwise_init("implicit")
struct Counter:
    var count: Int

def main():
    var c: Counter = 5  # implicitly converts from Int
```

## Copy constructor

In Mojo, a value can be copied either *explicitly* or *implicitly*:

```mojo
# Explicit copy
var s = "Test string"
var s2 = s.copy()

# Implicit copy
var i = 15
var i2 = i
```

To make a struct explicitly copyable, you need to:

- Add the `Copyable` trait.
- (Optionally) define a custom copy constructor if needed, written
  `def __init__(out self, *, copy: Self)`.

By adding the `Copyable` trait, Mojo can generate a default
copy constructor for you unless you've written one yourself.
This default method copies each field of the `copy` value
into the new value. The `Copyable` trait also defines a default
`copy()` method which provides an additional way to copy a value,
versus calling the copy constructor directly.

```mojo
@fieldwise_init
struct MyPet(Copyable):
    var name: String
    var age: Int
```

Now this code works to make a copy:

```mojo
var mine = MyPet("Loki", 4)
var yours = mine.copy()
```

:::note

Technically, you *could* make a struct with a copy constructor and *not* add the
`Copyable` trait, but this is not recommended. Mojo would be able to copy the
value, but you couldn't use the struct with any generic containers or functions
that require the `Copyable` trait.

:::

The generated copy constructor simply copies each field from the existing value
into the new value. For example, if you manually wrote the copy constructor for
`MyPet`, it would look like this:

```mojo
def __init__(out self, *, copy: Self):
    self.name = copy.name
    self.age = copy.age
```

This default copy constructor works in most cases, but there are a few cases
where you need to define a custom copy constructor:

- One or more of the struct's fields is not `Copyable`.
- The struct includes a non-owning type (like
  [`UnsafePointer`](/docs/std/memory/unsafe_pointer/UnsafePointer/)), and you
  want to make a deep copy of the data.
- The struct holds other resources (like file descriptors or network sockets)
  that need to be managed.

### Custom copy constructor

What makes Mojo's copy behavior different, compared to other languages, is that
copy constructor is designed to perform a deep copy of all fields in the type
(as per [value semantics](/docs/manual/values/value-semantics/)). That is,
it copies heap-allocated values, rather than just copying the pointer.

However, the Mojo compiler doesn't enforce this, so it's the type author's
responsibility to implement copy constructor with value semantics.

For example, here's a new `HeapArray` type with a custom copy constructor that
performs a deep copy:

```mojo
struct HeapArray(Copyable):
    var data: UnsafePointer[Int, MutExternalOrigin]
    var size: Int
    var cap: Int

    def __init__(out self, size: Int, val: Int):
        self.size = size
        self.cap = size * 2
        self.data = alloc[Int](https://mojolang.org/docs/manual/lifecycle/self.cap)
        for i in range(self.size):
            (self.data + i).init_pointee_copy(val)

    def __init__(out self, *, copy: Self):
        # Deep-copy the existing value
        self.size = copy.size
        self.cap = copy.cap
        self.data = alloc[Int](https://mojolang.org/docs/manual/lifecycle/self.cap)
        for i in range(self.size):
            (self.data + i).init_pointee_copy(copy.data[i])
        # The lifetime of `copy` continues unchanged

    def __del__(deinit self):
        # We must free the heap-allocated data, but
        # Mojo knows how to destroy the other fields
        for i in range(self.size):
            (self.data + i).destroy_pointee()
        self.data.free()

    def append(mut self, val: Int):
        # Update the array for demo purposes
        if self.size < self.cap:
            (self.data + self.size).init_pointee_copy(val)
            self.size += 1
        else:
            print("Out of bounds")

    def dump(self):
        # Print the array contents for demo purposes
        print("[", end="")
        for i in range(self.size):
            if i > 0:
                print(", ", end="")
            print(self.data[i], end="")
        print("]")
```

Notice that the copy constructor doesn't copy the `UnsafePointer` value (doing
so would make the copied value refer to the same `data` memory address as the
original value, which is a shallow copy). Instead, we initialize a new
`UnsafePointer` to allocate a new block of memory, and then copy over all the
heap-allocated values (this is a deep copy).

Thus, when we copy an instance of `HeapArray`, each copy has its own set of
values on the heap, so changes to one array do not affect the other, as shown
here:

```mojo
def copies():
    var a = HeapArray(2, 1)
    var b = a.copy()  # Calls the copy method
    a.dump()  # Prints [1, 1]
    b.dump()  # Prints [1, 1]

    b.append(2)  # Changes the copied data
    b.dump()  # Prints [1, 1, 2]
    a.dump()  # Prints [1, 1] (the original did not change)
```

Two other things to note from the copy constructor:

- The `copy` argument is type `Self` (capital "S"). `Self` is an alias for
  the current type name (`HeapArray`, in this example). Using this alias is a
  best practice to avoid any mistakes when referring to the current struct name.

- The `copy` argument is immutable because the default [argument
  convention](/docs/manual/values/ownership#argument-conventions) is
  an immutable reference. This is a good thing because this function
  shouldn't modify the contents of the value being copied.

:::note

In `HeapArray`, we must use the `__del__()` destructor to free the
heap-allocated data when the `HeapArray` lifetime ends, but Mojo automatically
destroys all other fields when their respective lifetimes end. We'll discuss
this destructor more in [Death of a value](/docs/manual/lifecycle/death/).

:::

If your type doesn't use any pointers for heap-allocated data, then writing the
constructor and copy constructor is all boilerplate code that you shouldn't have
to write. For most structs that don't manage memory explicitly, you can just add
the `Copyable` trait to your struct definition, and Mojo will synthesize the
copy constructor.

:::note

Mojo also calls upon the copy constructor when a value is passed to a
function that takes the argument as
[`var`](/docs/manual/values/ownership/#transfer-arguments-var-and-)
*and* when the lifetime of the given value does *not* end at that point. If the
lifetime of the value does end there (usually indicated with the transfer
sigil `^`), then Mojo instead invokes the move constructor.

:::

### Implicitly-copyable types

To make a type *implicitly copyable*, add the `ImplicitlyCopyable` trait:

```mojo
@fieldwise_init
struct MyPair(ImplicitlyCopyable):
    var first: Int
    var second: Int

def main():
    pair = MyPair(3, 4)
    copy = pair
    print(pair.first, copy.second)
```

The `ImplicitlyCopyable` trait refines `Copyable`, so adding
`ImplicitlyCopyable` to your type gives you `Copyable`'s copy
constructor and a `copy()` method. It also gives you automatic
`Movable` conformance.

The trait doesn't define any methods of its own: it serves as a signal
to the compiler that it can insert calls to copy constructor as needed. For
example, in the previous example, the compiler might generate code equivalent
to:

```mojo
pair = MyPair(3, 4)
copy = pair.copy()
```

A type should be implicitly copyable only if copying the type is inexpensive and
has no side effects. Unnecessary copies can be a big drain on memory and
performance, so use this trait with caution.

In particular, any type that dynamically allocates memory or manages other
resources probably shouldn't be implicitly copyable.

## Move constructor

Although copying values provides predictable behavior that matches Mojo's
[value semantics](/docs/manual/values/value-semantics/), copying some data
types can be a significant hit on performance.

Mojo uses the move constructor to transfer ownership of a value from one
variable to another, *without* copying its fields. A value that's copyable
but doesn't have a move constructor can still be transferred by making a copy
and then discarding the original. So in this case, the move constructor serves
as an optimization.

To make a type *movable*:

- Add the `Movable` trait *or* conform to `Copyable`.
- (Optionally) implement a custom move constructor.

Here's a movable (also copyable) version of the `MyPet` struct:

```mojo
@fieldwise_init
struct MyPet(Copyable):
    var name: String
    var age: Int
```

Here's an example showing how to invoke the move constructor for `MyPet`:

```mojo
def moves():
    var a = MyPet("Bobo", 2)

    print(a.name) # Prints "bobo"

    var b = a^ # the lifetime of `a` ends here

    print(b.name) # prints "bobo"
    # print(a.name)  # ERROR: use of uninitialized value 'a'
```

If you include the `Movable` trait and don't define a move constructor, Mojo
generates a default move constructor for you. This move constructor simply moves
each of the fields to the new instance.

The generated move constructor for `MyPet` would look like this if you wrote
it yourself:

```mojo
def __init__(out self, *, deinit take: Self):
    self.name = take.name^
    self.age = take.age
```

The move constructor takes its `take` argument using the `deinit`
[passing convention](/docs/manual/values/ownership/#argument-passing-conventions),
which grants exclusive ownership of the value and marks it as destroyed at the
end of the function. (For more information on the `deinit` convention, see
[Field lifetimes during destruct and move](/docs/manual/lifecycle/death/#field-lifetimes-during-destruct-and-move)).

The move constructor uses the transfer sigil (`^`) to indicate that
ownership of the `name` value transfers from `take` to `self`. For
trivial register-passable types like `Int`, omit the transfer sigil.
Trivial types are always movable. Since they can't define custom move
constructors or destructors, there's no special logic required to move.

At the end of the move constructor method, Mojo immediately invalidates the
original variable, preventing any access to it. Because the argument is declared
as `deinit`, it does *not* call the destructor, since that would destroy
resources that have been transferred to the
new instance. Invalidating the original variable is important to avoid memory
errors on heap-allocated data, such as use-after-free and double-free errors.

:::note

A move constructor is *not required* to transfer ownership of a
value. Mojo can copy the value and
invalidate the original instance. You can learn more in the section about
[ownership
transfer](/docs/manual/values/ownership#transfer-arguments-var-and-).

If copying a type is expensive, moving it with a move constructor is much
more efficient. For example, if a type has heap-allocated data, a copy
constructor typically needs to allocate new storage to make a deep copy of the
data.

For types without heap-allocated fields, you get no real benefit from the move
constructor. Making copies of simple data types on the stack, like integers,
floats, and booleans, is very cheap. Yet, if you allow your type to be copied,
then there's generally no reason to disallow moves.

:::

### Custom move constructor

In practice, structs very rarely require a custom move constructor. A type might
require a custom implementation if it has a pointer to itself or one of its
fields, for example, since the struct's location in memory changes when it's
moved.

The move constructor performs a consuming move: it [transfers
ownership](/docs/manual/values/ownership#transfer-arguments-var-and-) of a
value from one variable to another when the original variable's lifetime ends
(also called a "destructive move").

A critical feature of move constructors is that it takes the incoming value as a
`deinit` argument, meaning this method gets unique ownership of the value.
Moreover, because this is a dunder method that Mojo calls only when performing a
move (during ownership transfer), the `take` argument is guaranteed to be a
mutable reference to the original value, *not a copy* (unlike other methods that
may declare an argument as `var`, but might receive the value as a copy if the
method is called without the
[`^` transfer sigil](/docs/manual/values/ownership/#transfer-arguments-var-and-)).
That is, Mojo calls this move constructor *only* when the original variable's
lifetime actually ends at the point of transfer.

## Move-only and immovable types

To ensure your type can't be implicitly copied, you can make it "move-only" by
making it `Movable` but not `Copyable`. A move-only type can be
passed to other variables and passed into functions with any passing convention
(like `mut` or `var`.) The only catch is that you must use the `^`
transfer sigil to end the lifetime of a move-only type when assigning it to a
new variable or when passing it as a `var` argument. The
[`OwnedPointer`](/docs/std/memory/owned_pointer/OwnedPointer/) is an
example of a move-only type: because it is designed to provide clear single
ownership of a stored value, the `OwnedPointer` can be moved, but not copied.

In some (rare) cases, you may not want a type to be copyable *or* movable. The
[`Atomic`](/docs/std/atomic/atomic/Atomic/) type is an example of a type that's
neither copyable nor movable.

:::note Trivial types
Trivial types like `Int`, `Bool`, or `Float64` are the most common
types in systems programming. Mojo doesn't need special support for
these. They have no ownership semantics, no destructors, and are always
passed in CPU registers.
:::

### Trivial lifecycle methods

The use of a decorator to identify trivial types will be phased out in favor
of a more granular set of aliases, which are boolean flags set by the compiler:

- The `Copyable` trait defines the alias `__copy_ctor_is_trivial`, which is an
  optimization hint that guarantees that the value can be copied by its bits
  from one location to another without causing any side effects.

- The `Movable` trait defines the alias `__move_ctor_is_trivial`, which is an
  optimization hint that guarantees that the value can be moved by its bits
  from one location to another without causing any side effects.

- The `AnyType` trait defines the alias `__del__is_trivial`, which is a hint
  that the `__del__()` method is a no-op.
