Keep default constructor when adding a zero-argument constructor

If I add a zero-argument constructor Foo(), then I lose the ability to use the default constructor (e.g. Foo(1, 2)). This behavior is expected, and described in the documentation: If any inner constructor method is defined, no default constructor method is provided: it is presumed that you have supplied yourself with all the inner constructors you need.

If I want to keep the default constructor, I can create it by listing all arguments (or at least the correct number of arguments), but it seems like there should be a less-tedious way to maintain this part of the code. I tried using vargs Foo(args...) = new(args), but calling Foo(1, 2) with that strategy produces Foo((1, 2), #undef).

mutable struct Foo
  Foo() = new()
  #Foo(a, b) = new(a, b) # This works, but is not ideal
  #Foo(args...) = new(args) # Something like this would be better
  a
  b
end

Only if you add it as an inner constructor. Why can’t you add it as an outer constructor?

1 Like

Outer constructor does not have access to new().
So this doesn’t work:

mutable struct Foo
  a
  b
end
Foo() = new()
Foo()
ERROR: UndefVarError: new not defined

An inner constructor method is like an outer constructor method, except for two differences:
1. …
2. It has access to a special locally existent function called new that creates objects of the block’s type.

Outer constructor methods can only ever create a new instance by calling another constructor method, such as the automatically provided default ones.

So you want to be able to instantiate them with undef field values? OK.

Foo(args...) = new(args) # Something like this would be better

I guess you mean

Foo(args...) = new(args...)

That should work. The three dots after the input argument slurps them into a tuple. You have to splat them out again.

2 Likes

This appears to be not allowed (in Julia-1.1.0)

ERROR: syntax: ... is not supported inside "new"

Lucky Julia release timing for me then. I’m testing on Julia-1.2.0

1 Like