El viernes, 3 de junio de 2016, 22:06:20 (UTC-4), xdavidliu escribió: > > with > > > type foo > x::Int > foo(x) = x > 0 ? new(x) : new(-x) > end > > > type bar{T<:Integer} > x::T > end > > > type baz{T<:Integer} > x::T > baz(x) = x > 0 ? new(x) : new(-x) > end > > > > "foo(-5).x" gives 5, "bar(-5).x" gives -5, but "baz(-5).x" gives a > "MethodError: 'convert' has no method matching..." error. > > It seems the relevant section in the manual is this > <http://docs.julialang.org/en/release-0.4/manual/constructors/#parametric-constructors>, > > but I only have a single field (as opposed to the examples in the link in > which there are almost always two or more fields), so there should be no > type disagreement or ambiguity here. Is this intended behavior? >
This is rather subtle. The inner constructor defines *only* the parametrised constructor: julia> type baz{T<:Integer} x::T baz(x) = x > zero(x) ? new(x) : new(-x) end julia> methods(baz) 2-element Array{Any,1}: call{T}(::Type{T}, arg) at essentials.jl:56 call{T}(::Type{T}, args...) at essentials.jl:57 julia> baz{Int}(-5) baz{Int64}(5) If you want to use a non-parametrized constructor like baz(-5), you need to explicitly define it: julia> baz{T}(x::T) = baz{T}(x) Note that on the left, this means "for each T, define a function baz(x) for x of that type"; on the right it tells you to call the parametric constructor with *that particular* type T: julia> baz(-5) baz{Int64}(5)