# Class Constructor

**URL:** <https://discourse.julialang.org/t/class-constructor/95350>\
**Category:** New to Julia\
**Tags:** struct, constructors\
**Created:** [February 28, 2023, 7:46pm UTC](https://discourse.julialang.org/t/class-constructor/95350 "2023-02-28T19:46:01Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![Veenty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/veenty/32/50940_2.png) [@Veenty](https://discourse.julialang.org/u/Veenty)\
**Post date:** [February 28, 2023, 7:46pm UTC](https://discourse.julialang.org/t/class-constructor/95350/1 "2023-02-28T19:46:01Z")

</div>

I’m trying to generate a struct, and one of the of the elements of the struct depends on a parameter of the class. I’m not really sure how to do it tho

Example of what I’m doing

```julia
struct SpectralDiscretization1D

    Space
    kind #:Fourier, :Cheb1, :Cheb2, :Leg
    N #Number of points
    A #Matrix needed for change of coordinates, can it be FFT, DCT, LegMatrix, etc.
    A⁻¹ #Inverse of A 
    
    if kind == :Cheb1
        DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
        SpectralDiscretization1D(Space, kind, N) = new(Space, kind, N, DCT, DCT)    
        A = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
        A⁻¹ = A

    elseif kind == :Cheb2
        DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT10, 1, flags = FFTW.MEASURE)
        SpectralDiscretization1D(Space, kind, N) = new(Space, kind, N, DCT, DCT)

    end

end

```

But I get the error

`ERROR: UndefVarError: kind not defined`

What is the correct way of doing this?

---

<div class="post-metadata">

**Author:** ![Tomas\_Pevny](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomas_pevny/32/25466_2.png) [@Tomas\_Pevny](https://discourse.julialang.org/u/Tomas_Pevny)\
**Post date:** [February 28, 2023, 7:58pm UTC](https://discourse.julialang.org/t/class-constructor/95350/2 "2023-02-28T19:58:35Z")

</div>

You should be able to do this with inner constructor. There is an example in docs  
[https://docs.julialang.org/en/v1/manual/constructors/](https://docs.julialang.org/en/v1/manual/constructors/)  
How to do that.

---

<div class="post-metadata">

**Author:** ![Veenty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/veenty/32/50940_2.png) [@Veenty](https://discourse.julialang.org/u/Veenty)\
**Post date:** [February 28, 2023, 8:08pm UTC](https://discourse.julialang.org/t/class-constructor/95350/3 "2023-02-28T20:08:42Z")

</div>

I want to be able to give more than only 2 options (and hopefully not everything in one line) and I’m not sure how to extend the example of the documentation

---

<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 28, 2023, 8:31pm UTC](https://discourse.julialang.org/t/class-constructor/95350/4 "2023-02-28T20:31:11Z")

</div>

It doesn’t have to all be on one line. See below

```julia
julia> struct M
           x::Float64
           
           function M(x)
               if x > 1.0
                   x = 1.0
               elseif x < 0.0
                   x = 0.0
               end
               new(x)
           end
       end

julia> M(20.0)
M(1.0)

```

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [February 28, 2023, 8:31pm UTC](https://discourse.julialang.org/t/class-constructor/95350/5 "2023-02-28T20:31:13Z")

</div>

Sorry for nit-picking, but getting the terminology straight makes it a lot easier to find an actual solution to your problem.

- parameters (of a type/struct): see here [Types · The Julia Language](https://docs.julialang.org/en/v1/manual/types/#Parametric-Types)  
I think what you are referring to in the original question is the _fields_ of the struct (like `kind`, `N`, etc.) This difference is important, because perhaps what you really want to use are parameters
- class: doesn’t exist, but also doesn’t matter – structs also have constructors and as @Tomas_Pevny said, an inner constructor gives you the ability to compute the values of some fields based on the inputs to the constructor

Here is how that might work in your case:

```julia
struct SpectralDiscretization1D
    Space
    kind
    N
    A
    A⁻¹
    
    # Inner constructor – works like any other function except that it has to be in the struct block and should return some `new(...)` object
    function SpectralDiscretization1D(Space, kind, N)
        # Here goes your logic that constructs the fields based on, e.g. kind and N (or anything else
        if kind == :Cheb1
            DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
            A = FFTW.plan_r2r(ones(N) ,FFTW.REDFT00, 1, flags = FFTW.MEASURE)
            A⁻¹ = A
            return new(Space, kind, N, A, A⁻¹)
        elseif kind == :Cheb2
            DCT = FFTW.plan_r2r(ones(N) ,FFTW.REDFT10, 1, flags = FFTW.MEASURE)
            return = new(Space, kind, N, DCT, DCT)
        end
    end
end

```

Note that defining your own inner constructors will “overwrite” the default constructor. This might be what you want, but you can also just make the constructors “outer constructors” instead.

Just a tip: it might be worth fixing the _type_ of the fields of your struct to get more optimized compiled versions of your code.
