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)
 

Reply via email to