Julia类型参数在功能参数中嵌套/范围



从我之前发布的一个问题中跟进,我试图了解函数方法中类型参数范围的详细信息。
例如:

f(x::Vector{<:Number}) = sum(x)
g(x::Vector{T}) where T<:Number = sum(x)

<:Number约束仅涵盖f的参数列表:

julia> methods(f)
f(x::Array{#s1,1} where #s1<:Number)

,但看来g是由IT参数化的:

julia> methods(g)
g(x::Array{T,1}) where T<:Number

除了样式和限制 T的范围外," y ou通常希望 T覆盖尽可能少的签名?
是否有任何启示性能,派遣或代码生成?

确实,上面的 fg是等于迈克尔指出的。您可以通过写作动态检查它:

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"

关于正常(即类型稳定)代码的性能,Julia执行静态方法调度,因此这无关紧要。可能您可以设计一个人为的示例,需要复杂的动态方法调度或动态代码生成,这可能至关重要(但出于实际原因,这不应该是相关的 - 只需使用代表您需求的规范)。

fg语法是相同的,因此没有区别。

最新更新