# Accessing struct via Symbol

**URL:** <https://discourse.julialang.org/t/accessing-struct-via-symbol/58809>\
**Category:** General Usage\
**Tags:** loops, struct, setfield\
**Created:** [April 8, 2021, 8:40am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809 "2021-04-08T08:40:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mrVeng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrveng/32/8836_2.png) [@mrVeng](https://discourse.julialang.org/u/mrVeng)\
**Post date:** [April 8, 2021, 8:40am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809/1 "2021-04-08T08:40:22Z")

</div>

Dear all,

Is there a reason why this works:

```julia
struct Test1{A, B}
	a :: A
	b :: B
end
test1 = Test1(1., 2.)
test1.:a #1

```

but this does not work?

```julia
_a = :a
test1._a # type Test1 has no field _a

```

In my case I would like to update specific fields of `Test1` via the` Setfield.jl` package. MWE:

```julia
using Setfield
function func1(test, fldsymbols)
	for sym in fldsymbols
		test = @set test.sym = 3.
	end
	return nothing
end
func1(test1, (:a, ) ) #=ArgumentError: Failed to assign properties (:sym,) to object with fields (:a, :b). 
					    You may want to overload ConstructionBase.setproperties(obj::Test1{Float64, Float64}, patch::NamedTuple) =#

test1 = Setfield.@set test1.:a = 3. #this works fine though
test1.a #3

#Accessing via getfield(test1, sym) does not work and overrides the struct
test2 = Test1(4., 5.)
test2 = Setfield.@set getfield(test2, _a) = 6.
test2.a #type Float64 has no field a

```

In my real use case, changing only a single field of `Test1` via `Setfield.jl` is cheaper than creating a new struct. I do not want to use a mutable struct to avoid possible bugs. The fieldnames for `Test1` change though, so I usually store fields that I would like to change as symbols.

Best regards,

---

<div class="post-metadata">

**Author:** ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)\
**Post date:** [April 8, 2021, 9:00am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809/2 "2021-04-08T09:00:15Z")

</div>

You could use `@macroexpand` to see what `Setfield.@set` does and then code it up without the macro. Maybe easier, Setfield.jl’s docs also tells you what is going on: [Introduction · Setfield.jl](https://jw3126.github.io/Setfield.jl/stable/intro/#Under-the-hood).

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 8, 2021, 9:01am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809/3 "2021-04-08T09:01:21Z")

</div>

I _think_ you’ll need to construct your `Lens` manually (but Setfield makes that very easy):

```julia
julia> struct Foo
       a
       b
       end

julia> x = Foo(Foo(1,2),2)
Foo(Foo(1, 2), 2)

julia> p = :a
:a

julia> set(x, Setfield.PropertyLens{p}(), 5)
Foo(5, 2)

```

---

<div class="post-metadata">

**Author:** ![mrVeng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrveng/32/8836_2.png) [@mrVeng](https://discourse.julialang.org/u/mrVeng)\
**Post date:** [April 8, 2021, 10:51am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809/4 "2021-04-08T10:51:53Z")

</div>

Thank you!

Just so I understand correctly: Setfield.set will always create a new struct, and not inplace replace the fields? I.e.

```julia
using Setfield
x = Foo(1., 2.)
function func1(foo, val)
	for sym in fieldnames( typeof(foo) )
		foo = Setfield.set(foo, Setfield.PropertyLens{sym}(), val)
	end
	return foo
end
x.a #1.00
y = func1(x, 3.)
y.a #3.00
x.a #1.00

```

---

<div class="post-metadata">

**Author:** ![mrVeng](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrveng/32/8836_2.png) [@mrVeng](https://discourse.julialang.org/u/mrVeng)\
**Post date:** [April 8, 2021, 10:54am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809/5 "2021-04-08T10:54:10Z")

</div>

Thank you!

I will have a look at it to understand it better. I am trying to understand Macros better but it is a tough journey.

---

<div class="post-metadata">

**Author:** ![pfitzseb](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pfitzseb/32/45566_2.png) [@pfitzseb](https://discourse.julialang.org/u/pfitzseb)\
**Post date:** [April 8, 2021, 11:00am UTC](https://discourse.julialang.org/t/accessing-struct-via-symbol/58809/6 "2021-04-08T11:00:28Z")

</div>

Yes, you’re using immutable structs after all – it’s not legal to modify their fields.
