# Struct with property based on other properties

**URL:** https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181
**Category:** New to Julia
**Created:** [January 18, 2023, 9:04pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181 "2023-01-18T21:04:15Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![Eveee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eveee/32/45034_2.png) [@Eveee](https://discourse.julialang.org/u/Eveee)
#### Post date: [January 18, 2023, 9:04pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/1 "2023-01-18T21:04:15Z")

</div>

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:

```julia
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?

---

<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: [January 18, 2023, 9:09pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/2 "2023-01-18T21:09:18Z")

</div>

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](https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods).

```julia
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)

```

---

<div class="post-metadata">

### Author: ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)
#### Post date: [January 18, 2023, 9:14pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/3 "2023-01-18T21:14:38Z")

</div>

Or simply

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

```

---

<div class="post-metadata">

### Author: ![Eveee](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/eveee/32/45034_2.png) [@Eveee](https://discourse.julialang.org/u/Eveee)
#### Post date: [January 18, 2023, 9:20pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/4 "2023-01-18T21:20:51Z")

</div>

Thank you both!

---

<div class="post-metadata">

### Author: ![stephenll](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stephenll/32/28751_2.png) [@stephenll](https://discourse.julialang.org/u/stephenll)
#### Post date: [January 18, 2023, 10:58pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/5 "2023-01-18T22:58:17Z")

</div>

I’ve always used `getproperty` to accomplish this if using a `mutable struct`.

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

```

---

<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: [January 19, 2023, 4:37pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/6 "2023-01-19T16:37:04Z")

</div>

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:

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

```

---

<div class="post-metadata">

### Author: ![astro-kevin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/astro-kevin/32/43342_2.png) [@astro-kevin](https://discourse.julialang.org/u/astro-kevin)
#### Post date: [May 21, 2024, 1:45pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/7 "2024-05-21T13:45:18Z")

</div>

Is there a way to avoid having to type out the entire constructor again? For example something like

```julia
struct MyNumbers
    a::Int64
    b::Int64
    c::Int64
    d::Int64
    e::Int64
    MyNumbers(a, b, ...) = new(a, b, ..., a+b)
end

```

which obviously doesn’t work, but would be useful if there are a lot of properties that you don’t want to type out all over again.

---

<div class="post-metadata">

### Author: ![Dan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dan/32/42581_2.png) [@Dan](https://discourse.julialang.org/u/Dan)
#### Post date: [May 21, 2024, 2:03pm UTC](https://discourse.julialang.org/t/struct-with-property-based-on-other-properties/93181/8 "2024-05-21T14:03:39Z")

</div>

Something like:

```julia
julia> struct MyNumbers
           a::Int64
           b::Int64
           c::Int64
           d::Int64
           e::Int64
           MyNumbers(a, b, args...) = new(a, b, args..., a+b)
           end

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

```
