Julia类型参数在函数参数中的嵌套/范围

问题描述 投票:1回答:2

question I posted earlier之后,我试图理解函数方法中类型参数范围的细节。 例如:

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由它参数化:

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

"[y]ou generally want T to cover as little of the signature as possible"除了style和限制T的范围之外有什么原因? 是否有明显的性能,调度或代码生成的影响?

types julia type-variables
2个回答
4
投票

事实上,上面的fgMichael指出的相同。你可以写下来动态检查它:

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告诉你方法定义被覆盖(因此被认为是等价的)。

但是,总的来说确定范围很重要。看这个例子:

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执行静态方法调度,因此这无关紧要。可能你可以设计一个人为的例子,需要复杂的动态方法调度或动态代码生成,这可能很重要(但出于实际原因,这不应该是相关的 - 只需使用代表你需要的规范)。


1
投票

fg语法是相同的,所以没有区别。

© www.soinside.com 2019 - 2024. All rights reserved.