On Sun, Oct 11, 2015 at 6:54 PM, Andrei Zh <faithlessfri...@gmail.com> wrote: > I didn't know about such capability, thanks. But I still can't figure out > how to call this constructor. E.g.: > > julia> Bar{Int}() > ERROR: MethodError: `convert` has no method matching > convert(::Type{Bar{Int64}}) > This may have arisen from a call to the constructor Bar{Int64}(...), > since type constructors fall back to convert methods. > Closest candidates are: > convert{T}(::Type{T}, !Matched::T) > Bar{#s6,T}() > call{T}(::Type{T}, !Matched::Any) > in call at essentials.jl:57 > > Don't know if it matters, but I also have a different output of > `methods(Bar{Int})` than you: > > julia> methods(Bar{Int}) > 3-element Array{Any,1}: > call{#s6,T}(::Type{Bar{#s6}}) at > /home/<username>/work/playground/contructors.jl:11 > call{T}(::Type{T}, arg) at essentials.jl:56 > call{T}(::Type{T}, args...) at essentials.jl:57 >
The error I get (which seems to be different from yours) is ``` julia> type Bar{T} x::Array{T,1} Bar() = Bar(zeros(T, 10)) end julia> Bar{Int}() ERROR: MethodError: `convert` has no method matching convert(::Type{Bar{T}}, ::Array{Int64,1}) This may have arisen from a call to the constructor Bar{T}(...), since type constructors fall back to convert methods. Closest candidates are: call{T}(::Type{T}, ::Any) convert{T}(::Type{T}, ::T) in call at ./none:3 ``` And the issue here is that you cannot call the non-existing default inner constructor if you provide your own one. I suspect `Foo()` won't work for you either. The following works for me ``` julia> type Bar{T} x::Array{T,1} Bar() = new(zeros(T, 10)) end julia> Bar{Int}() Bar{Int64}([0,0,0,0,0,0,0,0,0,0]) ``` > > > > > On Monday, October 12, 2015 at 1:06:14 AM UTC+3, Yichao Yu wrote: >> >> On Sun, Oct 11, 2015 at 5:57 PM, Andrei Zh <faithle...@gmail.com> wrote: >> > Let's consider 2 types with inner constructors: >> > >> > type Foo >> > x::Array{Int,1} >> > >> > >> > Foo() = Foo(zeros(Int, 10)) >> > end >> > >> > type Bar{T} >> > x::Array{T,1} >> > >> > >> > Bar() = Bar(zeros(T, 10)) >> > end >> > >> > The only difference between them is that `Bar` has type parameter while >> > `Foo` doesn't. I'd expect their inner constructors behave the same way, >> > but >> > `Bar` turns to ignore inner constructor definition: >> > >> > julia> methods(Foo) >> > 3-element Array{Any,1}: >> > call(::Type{Foo}) at /home/<username>/work/playground/contructors.jl:5 >> > call{T}(::Type{T}, arg) at essentials.jl:56 >> > call{T}(::Type{T}, args...) at essentials.jl:57 >> > >> > >> > julia> methods(Bar) >> > 2-element Array{Any,1}: >> > call{T}(::Type{T}, arg) at essentials.jl:56 >> > call{T}(::Type{T}, args...) at essentials.jl:57 >> > >> > Is it a bug or a feature and how to make `Bar` recognize inner >> > constructor >> > (outer constructor is not an option here since it uses type parameter >> > `T` in >> > constructor body, but not in its constructor)? >> > >> >> As you pointed out, the inner constructor can access the type >> parameter and therefore the type parameter needs to be specified in >> order to call it. >> >> julia> methods(Bar{Int}) >> 3-element Array{Any,1}: >> call{T}(::Type{Bar{T}}) at none:3 >> call{T}(::Type{T}, arg) at essentials.jl:55 >> call{T}(::Type{T}, args...) at essentials.jl:56