# Struct with property based on other properties

Hi all,

I am learning to use structs in Julia, specifically I have a set of integers that I would like to access throughout some calculations:

``````struct MyNumbers
a::Int64
b::Int64
c=a+b
end
``````

However, the assignment of c gives me a syntax error, what would be the correct way to do this?

You would use an â€śinner constructorâ€ť to ensure `c` always has the right value. And an â€śouter constructorâ€ť to create a new instance where `c` is given the correct value. See the docs here.

``````julia> struct MyNumbers
a::Int64
b::Int64
c::Int64
MyNumbers(a, b, c) = begin
@assert c == a + b
new(a, b, c)
end
end;

julia> MyNumbers(a, b) = MyNumbers(a, b, a + b);

julia> MyNumbers(1, 2, 5)
ERROR: AssertionError: c == a + b
Stacktrace:
[1] MyNumbers(a::Int64, b::Int64, c::Int64)
@ Main ./REPL[1]:6
[2] top-level scope
@ REPL[3]:1

julia> MyNumbers(1, 2, 3)
MyNumbers(1, 2, 3)

julia> MyNumbers(1, 2)
MyNumbers(1, 2, 3)
``````
4 Likes

Or simply

``````struct MyNumbers
a::Int64
b::Int64
c::Int64
MyNumbers(a, b) = new(a, b, a+b)
end
``````
6 Likes

Thank you both!

Iâ€™ve always used `getproperty` to accomplish this if using a `mutable struct`.

``````function Base.getproperty(x::MyNumbers, sym::Symbol)
if sym == :c
returns x.a + x.b
else
return getfield(x, sym)
end
end
``````
4 Likes

If your extra field requires some expensive calculation, then you can precompute it using a constructor, as people have suggested.

However, for simple calculations, the `getproperty` approach suggested above is nicer because it doesnâ€™t actually use the extra memory and wonâ€™t become wrong if you change `a` or `b` (although in your example, `MyNumbers` is immutable so this wonâ€™t happen).

`getproperty` can sometimes be a little tedious to define, though. So my preferred approach (and the most flexible) is to access objects through accessor functions. Personally, I almost never use direct field access outside of defining an accessor. For example:

``````geta(x::MyNumbers) = x.a
getb(x::MyNumbers) = x.b
getc(x::MyNumbers) = geta(x) + getb(x) # or x.a + x.b
``````
2 Likes