I have a hard time defining a constructor for a parametric type
struct Point{T}
x::T
y::T
Point{T}(x,y) where {T} = new(x,y)
end
Point(0.0, 0.0)
# ERROR: MethodError: no method matching Point(::Float64, ::Float64)
What am I missing?
I have a hard time defining a constructor for a parametric type
struct Point{T}
x::T
y::T
Point{T}(x,y) where {T} = new(x,y)
end
Point(0.0, 0.0)
# ERROR: MethodError: no method matching Point(::Float64, ::Float64)
What am I missing?
The constructor you’ve defined (Point{T}(x, y)
) is invoked when the T
parameter is explicitly given, like this:
Point{Float64}(0.0, 0.0)
The reason this is happening is that by defining your own inner constructor, you’ve overwritten the default inner constructor for your type. You could fix this by defining a more flexible inner constructor:
struct Point{T}
x::T
y::T
Point(x::T, y::T) where {T} = new{T}(x, y) # called with Point(x, y)
Point{T}(x, y) where {T} = new{T}(x, y) # called with Point{T}(x, y)
end
julia> Point(0.0, 0.0)
Point{Float64}(0.0, 0.0)
julia> Point{Int}(0.0, 0.0)
Point{Int64}(0, 0)
Is there any advantage/difference between what you have posted and
struct Point{T}
x::T
y::T
Point{T}(x, y) where {T} = new{T}(x, y) # called with Point{T}(x, y)
end
Point(x::T, y::T) where {T} = Point{T}(x, y) # called with Point(x, y)
@musm actually I think your version is more standard, but I’m not super clear on the distinction.
Same for dispatch. Putting it in the type def allows access to new
keyword to construct the object without proxy though another constrictor
I’d prefer the inner constructor to avoid that tiny code repetition (new
vs Point
).
Wouldn’t the compiler inline this anyway?
From the perspective of coding style, inner constructors are generally justified when they provide something extra (incomplete initialization, checking consistency), in which case it may be better to pack the extra functionality in a few inner constructors (ideally one), and call that.
Inlining isn’t the issue at all. Having access to new
means that you are not constraint by the signature of defined constructors and can construct the object directly.