Julia 如何使用`hasmethod`(或任何其他方式)查找`hasmethod(fn,元组{Type1,Type2,**任何类型**})`

Julia 如何使用`hasmethod`(或任何其他方式)查找`hasmethod(fn,元组{Type1,Type2,**任何类型**})`,julia,Julia,我想使用hasmethod函数来查找对象t::t是否支持t[!,something]语法 关键是something可以有很多类型,我不想全部检查,我只想用一种方式来表达hasmethod(getindex,Tuple{t,typeof{!},S})而不管S是什么 如何做到这一点?如果语法正确,理论上可以做到: julia> hasmethod(getindex, Tuple{Vector{Int}, typeof(!), Any}) true 这应该是可行的,因为元组是协变的 但它返回的

我想使用
hasmethod
函数来查找对象
t::t
是否支持
t[!,something]
语法

关键是
something
可以有很多类型,我不想全部检查,我只想用一种方式来表达
hasmethod(getindex,Tuple{t,typeof{!},S})
而不管
S
是什么


如何做到这一点?

如果语法正确,理论上可以做到:

julia> hasmethod(getindex, Tuple{Vector{Int}, typeof(!), Any})
true
这应该是可行的,因为元组是协变的

但它返回的
true
显然是无稽之谈:

julia> getindex([1], !, 1)
ERROR: ArgumentError: invalid index: ! of type typeof(!)
Stacktrace:
 [1] to_index(::Function) at ./indices.jl:270
 [2] to_index(::Array{Int64,1}, ::Function) at ./indices.jl:247
 [3] to_indices(::Array{Int64,1}, ::Tuple{Base.OneTo{Int64}}, ::Tuple{typeof(!),Int64}) at ./indices.jl:298
 [4] to_indices at ./indices.jl:294 [inlined]
 [5] getindex(::Array{Int64,1}, ::Function, ::Int64) at ./abstractarray.jl:981
 [6] top-level scope at REPL[26]:1
原因是,它在内部授权


我认为最好是将
T
约束到某种抽象类型,而这种类型的索引是已知的。或者,作为最后手段,使用
try

我认为获得方法列表的方法是:

methods(getindex, Tuple{Any, typeof(!), Any})
唯一的问题是,如果
getindex
允许的第二个参数是
typeof(!)
的超类型,那么它也将被列出。但我认为这是无法避免的,因为您不能排除这样的
getindex
定义实际上允许

例如,如果未加载任何包,则上述调用的结果如下:

julia> methods(getindex, Tuple{Any, typeof(!), Any})
# 10 methods for generic function "getindex":
[1] getindex(md::Markdown.MD, args...) in Markdown at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.2\Markdown\src\parse\parse.jl:24
[2] getindex(r::Distributed.Future, args...) in Distributed at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.2\Distributed\src\remotecall.jl:624
[3] getindex(::Type{Any}, vals...) in Base at array.jl:357
[4] getindex(::Type{T}, x, y) where T in Base at array.jl:353
[5] getindex(::Type{T}, vals...) where T in Base at array.jl:344
[6] getindex(A::SparseArrays.SparseMatrixCSC, i, ::Colon) in SparseArrays at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.2\SparseArrays\src\sparsematrix.jl:1879
[7] getindex(A::AbstractArray, I...) in Base at abstractarray.jl:979
[8] getindex(t::AbstractDict, k1, k2, ks...) in Base at abstractdict.jl:476
[9] getindex(itr::Base.SkipMissing, I...) in Base at missing.jl:232
[10] getindex(r::Distributed.RemoteChannel, args...) in Distributed at C:\cygwin\home\Administrator\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.2\Distributed\src\remotecall.jl:626
所有情况下,
getindex
都没有对第二个参数施加限制,因此不能排除它们可能允许
作为有效值

但是,如果加载DataFrames.jl并将第一个参数限制为
AbstractDataFrame
,则会得到:

julia> methods(getindex, Tuple{AbstractDataFrame, typeof(!), Any})
# 5 methods for generic function "getindex":
[1] getindex(df::DataFrame, ::typeof(!), col_ind::Symbol) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\dataframe\dataframe.jl:367
[2] getindex(df::DataFrame, ::typeof(!), col_ind::Union{Signed, Unsigned}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\dataframe\dataframe.jl:358

[3] getindex(df::DataFrame, row_ind::typeof(!), col_inds::Union{Colon, Regex, AbstractArray{T,1} where T, All, Between, InvertedIndex}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\dataframe\dataframe.jl:405
[4] getindex(sdf::SubDataFrame, ::typeof(!), colind::Union{Signed, Symbol, Unsigned}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\subdataframe\subdataframe.jl:127
[5] getindex(df::SubDataFrame, row_ind::typeof(!), col_inds::Union{Colon, Regex, AbstractArray{T,1} where T, All, Between, InvertedIndex}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\subdataframe\subdataframe.jl:137
现在它的信息量更大了,因为在DataFrames.jl中,我们尽量小心不要让索引参数处于空闲状态(即允许它们是
Any
,并且只在内部检查什么是有效的)

此外,您还可以使用带有
方法来检查哪些方法接受
并仅过滤
getindex
实例。以下是加载DataFrames.jl后的结果:

julia> filter(x -> x.name == :getindex, methodswith(typeof(!)))
[1] getindex(df::DataFrame, ::typeof(!), col_ind::Symbol) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\dataframe\dataframe.jl:367
[2] getindex(df::DataFrame, ::typeof(!), col_ind::Union{Signed, Unsigned}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\dataframe\dataframe.jl:358

[3] getindex(df::DataFrame, row_ind::typeof(!), col_inds::Union{Colon, Regex, AbstractArray{T,1} where T, All, Between, InvertedIndex}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\dataframe\dataframe.jl:405
[4] getindex(sdf::SubDataFrame, ::typeof(!), colind::Union{Signed, Symbol, Unsigned}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\subdataframe\subdataframe.jl:127
[5] getindex(df::SubDataFrame, row_ind::typeof(!), col_inds::Union{Colon, Regex, AbstractArray{T,1} where T, All, Between, InvertedIndex}) in DataFrames at D:\AppData\.julia\packages\DataFrames\yH0f6\src\subdataframe\subdataframe.jl:137

最后请注意,
x[!,y]
语法也可以表示
视图
(如果前面有
@view
)或
设置索引操作(如果它出现在分配的左侧),因此如果这些函数接受
,您可能还想检查它们(在DataFrames.jl中,它们实际上是这样的)。

我认为您的答案并没有完全回答这个问题。例如,考虑<代码> FoO(x::Int,y::FulAT64,Z::string)=“$x+$y”*“**”。如果我使用hasmethod(foo,Tuple{Int,Float64,Any})
我得到false。OP想找到一种方法,不管最后一个参数上的签名是什么,都能起作用。哦,是的,你说得对。明天我会看一看。
方法(getindex,Tuple{T,typeof(!),Any})
因为我知道类型是
T