# Recommended way to destructuring a type

**URL:** <https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103>\
**Category:** General Usage\
**Tags:** question, iterators\
**Created:** [May 13, 2026, 12:46pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103 "2026-05-13T12:46:42Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 13, 2026, 12:46pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/1 "2026-05-13T12:46:42Z")

</div>

I would like to provide [destructuring assignment](https://docs.julialang.org/en/v1/manual/functions/#destructuring-assignment) as a syntactic sugar for a custom type.

I understand that the way to do it is iteration, but I am wondering if there is something more elegant than the MWE below, also compiler-friendly (constant folding of iterator state).

```julia
struct Foo{T}
    a::T
    b::T
    c::T
end

function Base.iterate(foo::Foo, index = 1)
    if index == 1
        foo.a, 2
    elseif index == 2
        # NOTE: deliberately reverse c, b
        foo.c, 3
    elseif index == 3
        foo.b, 4
    else
        nothing
    end
end

```

which works as

```julia
julia> x, y, z = Foo(1, 2, 3);

julia> (x, y, z)
(1, 3, 2)

```

That is to say, is there a convenient shortcut which would just tell destructuring to collect the fields `(:a, :c, :b)`?

Just to clarify, the user would still manually specify the result, just not define the rather inelegant `Base.iterate` above.

---

<div class="post-metadata">

**Author:** ![martincornejo](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/martincornejo/32/13436_2.png) [@martincornejo](https://discourse.julialang.org/u/martincornejo)\
**Post date:** [May 13, 2026, 12:51pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/2 "2026-05-13T12:51:16Z")

</div>

Named tuple:

```julia
(; a, b, c) = Foo(1,2,3)

```

Works also with single fields

```julia
(; b) = Foo(5,6,7)

```

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 13, 2026, 12:55pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/3 "2026-05-13T12:55:43Z")

</div>

That was not my question; I specifically want destructuring via iterables (as linked in the docs), not property-based destructuring.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [May 13, 2026, 12:55pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/4 "2026-05-13T12:55:45Z")

</div>

you could also do something along the lines of `iterate(f::Foo, i=1) = (i <= nfields(f)) ? (getfield(f, i), i+1) : nothing`

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 13, 2026, 12:56pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/5 "2026-05-13T12:56:15Z")

</div>

Note how `b` and `c` are exchanged, that is deliberate in the MWE.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [May 13, 2026, 12:58pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/6 "2026-05-13T12:58:59Z")

</div>

perhaps instead of `getfield(f, i)` you can define some const permutation and make that `getfield(f, PERM[i])` ?

or: `iterate(f::Foo, state...) = iterate((f.a, f.c, f.b), state...)`

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [May 13, 2026, 1:07pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/7 "2026-05-13T13:07:28Z")

</div>

This is a bit wacky, as it hides the result in the state:

```julia
# this can be reused, eg from a package
function proxy_iterate((proxy, inner_state...),)
    result = iterate(proxy, inner_state...)
    if result ≡ nothing
        nothing
    else
        elt, inner_state′ = result
        elt, (proxy, inner_state′)
    end
end

# the user would define this
Base.iterate(foo::Foo, state = ((foo.a, foo.c, foo.b), )) = proxy_iterate(state)

```

---

<div class="post-metadata">

**Author:** ![matthias314](https://avatars.discourse-cdn.com/v4/letter/m/a88e4f/32.png) [@matthias314](https://discourse.julialang.org/u/matthias314)\
**Post date:** [May 13, 2026, 4:22pm UTC](https://discourse.julialang.org/t/recommended-way-to-destructuring-a-type/137103/8 "2026-05-13T16:22:32Z")

</div>

You could convert your type to `Tuple` and use `Tuple` iteration:

```julia-auto
Base.Tuple(foo::Foo) = (foo.a, foo.c, foo.b)
Base.iterate(foo::Foo, state...) = iterate(Tuple(foo), state...)

```
