Действительно f
и g
выше эквивалентны, как Майкл .Вы можете динамически проверить это, написав:
julia> f(x::Vector{<:Number}) = sum(x)
f (generic function with 1 method)
julia> f(x::Vector{T}) where T<:Number = sum(x)
f (generic function with 1 method)
julia> methods(f)
# 1 method for generic function "f":
[1] f(x::Array{T,1}) where T<:Number in Main at REPL[2]:1
И Джулия говорит вам, что определение метода было перезаписано (так что оно было признано эквивалентным).
Однако в общем случае определение объемаиметь значение.См. Этот пример:
julia> f(::Vector{Vector{<:Real}}) = "inner"
f (generic function with 1 method)
julia> f(::Vector{Vector{T}}) where {T<:Real}= "outer"
f (generic function with 2 methods)
julia> f(::Any) = "all else"
f (generic function with 3 methods)
julia> methods(f)
# 3 methods for generic function "f":
[1] f(::Array{Array{#s1,1} where #s1<:Real,1}) in Main at REPL[1]:1
[2] f(::Array{Array{T,1},1}) where T<:Real in Main at REPL[2]:1
[3] f(::Any) in Main at REPL[3]:1
julia> f([[1]])
"outer"
julia> f(Vector{<:Real}[[1]])
"inner"
julia> f([Any[1]])
"all else"
Что касается производительности в нормальном (т.е. стабильном по типу) коде, Джулия выполняет статическую диспетчеризацию метода, поэтому это не должно иметь значения.Возможно, вы могли бы разработать надуманный пример, требующий сложной динамической отправки методов или генерации динамического кода, где это может иметь значение (но по практическим соображениям это не должно быть актуально - просто используйте спецификацию, соответствующую вашим потребностям).