# Creating a struct from a Named Tuple

**URL:** <https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586>\
**Category:** General Usage\
**Tags:** struct, namedtuple\
**Created:** [February 13, 2023, 9:42pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586 "2023-02-13T21:42:52Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [February 13, 2023, 9:42pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/1 "2023-02-13T21:42:52Z")

</div>

Is there any function like `similar` which creates a `struct` inhering the names and types of a `NamedTuple`?

MEW:

```julia
nt = (a = 1, b ="Hello")

#some function like 
MyStruct = similar(nt)

#`similar` would create this:
struct MyStruct
    a::Int64
    b::String
end

```

My question is because you can easily convert a SubDataFrame into a NamedTuple. So, retrieving some data and putting it into a model can be easily done through a NamedTuple. However, there doesn’t seem to be an easy way to move from a SubDataFrame to a `struct`, unless you repeat the name of each variable and the type of each variable (which is long and prone to error if you have 20 variables).

Many thanks

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 13, 2023, 9:55pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/2 "2023-02-13T21:55:12Z")

</div>

1. Don’t overload `similar` on types you don’t own. Define a constructor instead

2. One thing you can do is use the `@with_kw` macro

```julia
@with_kw struct MyStruct
    a::Int64
    b::String
end

```

```julia
MyStruct(; nt...)

```

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [February 13, 2023, 10:00pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/3 "2023-02-13T22:00:40Z")

</div>

The name `similar` was just an example. But, in any case, I’m actually asking for the other way of the conversion: going from a `NamedTuple` to a `struct`.

---

<div class="post-metadata">

**Author:** ![pdeffebach](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pdeffebach/32/10320_2.png) [@pdeffebach](https://discourse.julialang.org/u/pdeffebach)\
**Post date:** [February 13, 2023, 10:07pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/4 "2023-02-13T22:07:50Z")

</div>

Yes, my example gives you that.

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [February 13, 2023, 10:21pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/5 "2023-02-13T22:21:58Z")

</div>

Thanks, my point is that I want to avoid defining the `struct`. So, I was wondering if there’s a function `foo` where you can do

```julia
nt = (a = 1, b ="Hello")

MyStruct = foo(nt) 

```

where `MyStruct` gives you a `struct` identifying the names and types from `nt`.

Put differently, I’m trying to avoid the need to write:

```julia
Base.@kwdef struct MyStruct
    a::Int64
    b::String
end

```

by using the functino `foo` that figures out the names and types.

---

<div class="post-metadata">

**Author:** ![mikmoore](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mikmoore/32/31109_2.png) [@mikmoore](https://discourse.julialang.org/u/mikmoore)\
**Post date:** [February 13, 2023, 10:36pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/6 "2023-02-13T22:36:16Z")

</div>

The main purpose I would imagine for making a `struct` defined based on a `NamedTuple` would be in order to have your own type for dispatch without pirating functions on `NamedTuple`.

For this, I’ll instead propose you make a thin wrapper over `NamedTuple`. For an immutable structure, this is all you need for the wrapper approach:

```julia
struct MyStruct{NT<:NamedTuple}
	nt::NT
end

Base.getproperty(x::MyStruct,y::Symbol) = Base.getproperty(getfield(x,:nt),y)

# now test it
x = MyStruct((;a=1,b="two"))
x.b # can access via the fieldnames of the NamedTuple

```

Note that (with this definition of `getproperty`) the only way to access the `nt` field of `MyStruct` is via an explicit call to `getfield` (ie, `x.nt` will look for a `nt` field within the NamedTuple instead).

There will be all sorts of stumbling blocks if you want to define a standalone struct based on an instance of a `NamedTuple`. It’s literally possible, but will be based on `eval` and will have horrible performance even once you do get it “working”. It will also likely cause lots of world age errors when you try to use it.

---

<div class="post-metadata">

**Author:** ![alfaromartino](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/alfaromartino/32/52986_2.png) [@alfaromartino](https://discourse.julialang.org/u/alfaromartino)\
**Post date:** [February 13, 2023, 10:59pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/7 "2023-02-13T22:59:04Z")

</div>

Thanks!! this is what I was looking for

---

<div class="post-metadata">

**Author:** ![Nathan\_Boyer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nathan_boyer/32/14825_2.png) [@Nathan\_Boyer](https://discourse.julialang.org/u/Nathan_Boyer)\
**Post date:** [February 14, 2023, 2:15pm UTC](https://discourse.julialang.org/t/creating-a-struct-from-a-named-tuple/94586/8 "2023-02-14T14:15:36Z")

</div>

You can also just dispatch on NamedTuple (no need for a Struct) if you will be defining all your own functions. Here are two methods I use.

```julia
# Define the function to accept keyword arguments.
# Splat a named tuple to call it.
# Keyword argument order doesn't matter since they are named.
# `c...` will slurp up any unused elements of the named tuple.
function f(; b, a, c...)
    println(a+1)
    println(reverse(b))
end

# Define the function to accept normal positional arguments.
# Add a method which deconstructs the named tuple and calls the main method.
function g(a, b)
    println(a+2)
    println(uppercase(b))
end
g(nt::NamedTuple) = g(nt.a, nt.b)

```

```julia
julia> nt = (a=1, b="Hello", c=:extra1, d=:extra2)
(a = 1, b = "Hello", c = :extra1, d = :extra2)

julia> f(; nt...)
2
olleH

julia> g(nt)
3
HELLO

```
