# Hide default constructor for a struct

**URL:** <https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 21, 2022, 2:08pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064 "2022-10-21T14:08:42Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![prittjam](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/prittjam/32/21267_2.png) [@prittjam](https://discourse.julialang.org/u/prittjam)\
**Post date:** [October 21, 2022, 2:08pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/1 "2022-10-21T14:08:42Z")

</div>

Is there a way to hide a default constructor for a struct so that it is not callable?

Thanks.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [October 21, 2022, 2:12pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/2 "2022-10-21T14:12:49Z")

</div>

You can certainly _replace_ the default constructor by a custom one. But dropping it without any replacement isn’t particularly useful, is it? If there is no constructor at all, what do you need the struct for (you will never be able to create objects)?

```julia
julia> struct A
           x::Float64
           A() = new(1.23)
       end

julia> A() # custom constructor
A(1.23)

julia> A(3.141) # default constructor isn't defined
ERROR: MethodError: no method matching A(::Float64)
Closest candidates are:
  A() at REPL[1]:3
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

```

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [October 21, 2022, 2:24pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/3 "2022-10-21T14:24:59Z")

</div>

FWIW, you can also delete the constructor methods after defining the struct.

```julia
julia> struct A
           x::Float64
       end

julia> Base.delete_method.(methods(A));

julia> methods(A)
# 0 methods for type constructor

julia> A()
ERROR: MethodError: no method matching A()

```

But again, I don’t get the point and wouldn’t recommend it 🙂

---

<div class="post-metadata">

**Author:** ![olivierverdier](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/olivierverdier/32/50887_2.png) [@olivierverdier](https://discourse.julialang.org/u/olivierverdier)\
**Post date:** [September 29, 2023, 1:05pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/4 "2023-09-29T13:05:27Z")

</div>

You can also disable the default constructor by making `struct` dependent on another (arbitrary) type:

```julia
struct A{T}
      x::Float64
end
A(3.1) # error
A{Any}(3.1) # works

```

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [September 29, 2023, 1:09pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/5 "2023-09-29T13:09:10Z")

</div>

You can also just do this:

```julia
julia> struct A
           f() = nothing
       end

julia> methods(A)
# 0 methods for type constructor

```

---

<div class="post-metadata">

**Author:** ![\_bernhard](https://avatars.discourse-cdn.com/v4/letter/_/bc79bd/32.png) [@\_bernhard](https://discourse.julialang.org/u/_bernhard)\
**Post date:** [September 30, 2023, 2:05pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/6 "2023-09-30T14:05:48Z")

</div>

Is this behavior to be considered a bug or a feature?

---

<div class="post-metadata">

**Author:** ![jakobnissen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jakobnissen/32/13477_2.png) [@jakobnissen](https://discourse.julialang.org/u/jakobnissen)\
**Post date:** [September 30, 2023, 2:06pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/7 "2023-09-30T14:06:36Z")

</div>

No idea. It certainly looks buggy and arguably it should error out - but it doesn’t.

---

<div class="post-metadata">

**Author:** ![\_bernhard](https://avatars.discourse-cdn.com/v4/letter/_/bc79bd/32.png) [@\_bernhard](https://discourse.julialang.org/u/_bernhard)\
**Post date:** [September 30, 2023, 2:07pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/8 "2023-09-30T14:07:07Z")

</div>

That was also my impression…

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [September 30, 2023, 7:15pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/9 "2023-09-30T19:15:44Z")

</div>

```julia
julia> struct A{F}
           f() = println("Hello world")
           x::F
           A() = new{typeof(f)}(f)
       end

julia> A().x()
Hello world

julia> A()
A{var"#f#4"}(var"#f#4"())

julia> f()
ERROR: UndefVarError: `f` not defined
Stacktrace:
 [1] top-level scope
   @ REPL[10]:1

```

---

<div class="post-metadata">

**Author:** ![Tortar](https://avatars.discourse-cdn.com/v4/letter/t/6bbea6/32.png) [@Tortar](https://discourse.julialang.org/u/Tortar)\
**Post date:** [December 20, 2023, 4:12pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/10 "2023-12-20T16:12:09Z")

</div>

> [@\_bernhard](#):
>
> Is this behavior to be considered a bug or a feature?

Still not sure :D: [Wrongly named inner constructor doesn't error · Issue #52580 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/issues/52580)

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 20, 2023, 8:15pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/11 "2023-12-20T20:15:19Z")

</div>

Not a bug. The struct has local scope and you can evaluate arbitrary code inside to define ways to construct objects of the type. The most common way to do this is to add methods to the type object itself, but you can do other things as well, eg define a single globally bound instance or a global function by another name that constructs them. If there is any code in a strict you don’t get a default constructor.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [December 20, 2023, 8:52pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/12 "2023-12-20T20:52:49Z")

</div>

> [@StefanKarpinski](#):
>
> The struct has local scope and you can evaluate arbitrary code inside

No variable assignments in the struct’s outermost scope, right, it throws a syntax error?

> [@StefanKarpinski](#):
>
> eg define a single globally bound instance or a global function by another name that constructs them.

These could’ve been done in the global scope without global declarations or `eval`s. Is there anything that _must_ be done in the `struct`’s local scope besides the inner constructors?

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 21, 2023, 11:33am UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/13 "2023-12-21T11:33:54Z")

</div>

Yes, there are some syntax restrictions—it can’t clash with field declaration or the reserved syntax for defining default values for them.

The point of doing these things inside the struct is that it’s easy to prove that they are the only ways that an object of the type can be constructed since the new pseudo-function is only available inside there. If you do it outside then you had to make some constructor method available and anyone could call that so there’s no such guarantee.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [December 21, 2023, 12:53pm UTC](https://discourse.julialang.org/t/hide-default-constructor-for-a-struct/89064/14 "2023-12-21T12:53:49Z")

</div>

> [@carstenbauer](#):
>
> You can certainly _replace_ the default constructor by a custom one. But dropping it without any replacement isn’t particularly useful, is it? If there is no constructor at all, what do you need the struct for (you will never be able to create objects)?

Just note this is not 100% true… in ConstructionBase.jl we actually do construct objects without constructors! (like anonymous function functors)

> <https://github.com/JuliaObjects/ConstructionBase.jl/blob/master/src/functions.jl#L13>
