using Parameters
struct Cat
breed
colour
age
weight
name
end
@with_kw struct Pet
name
kind
age
function Pet(cat::Cat)
new(name= cat.name, kind = typeof(cat), age = cat.age)
end
end
fluffy = Cat("Fluffy", "White", 2, 10, "Fluffy")
pet = Pet(cat)
Here, there’s a constructor to easily make Pet instances from a Cat instance, but this gives the error
ERROR: syntax: "new" does not accept keyword arguments around
julia> using Parameters
julia> struct Cat
breed
colour
age
weight
name
end
julia> @with_kw struct Pet
name
kind
age
end
Pet
julia> Pet(c::Cat) = Pet(name=c.name, kind=typeof(c), age=c.age)
Pet
julia> c = Cat("None", "Black", 5, 5.0, "John")
Cat("None", "Black", 5, 5.0, "John")
julia> Pet(c)
Pet
name: String "John"
kind: Cat <: Any
age: Int64 5
You only need inner constructors if you want a Pet(a,b,c) constructor, which may be ambiguous with the default constructor.
Thanks for your reply, while this is a sensible answer there’s two reasons why I’d rather not use this method:
I’d prefer for the constructor to be defined in the struct, it seems like a nicer syntax, and it is also more in keeping with a non-Parameters.jl approach
This method doesn’t work within Pluto notebooks, I appreciate I didn’t mention this in the initial question though
That is not the most common view. Inner constructions are the exception, not the rule.
You can just put them in a begin... end block, as suggested by the error message.
Anyway, both these are styling choices, you are not really limited by the functionality. But you can use an inner constructor without the keyword arguments, if you want:
julia> @with_kw struct Pet
name
kind
age
Pet(c::Cat) = new(c.name, typeof(c), c.age)
end
julia> c = Cat("None", "Black", 5, 5.0, "John")
Cat("None", "Black", 5, 5.0, "John")
julia> Pet(c)
Pet
name: String "John"
kind: Cat <: Any
age: Int64 5