Reflection 如何检查给定的'Method'对象是否接受Julia 0.6中给定的'Tuple'类型?

Reflection 如何检查给定的'Method'对象是否接受Julia 0.6中给定的'Tuple'类型?,reflection,julia,multiple-dispatch,Reflection,Julia,Multiple Dispatch,目标是定义一个函数,该函数采用一个方法和一个类型元组, 并返回true。这些类型是该方法的有效输入。 非功能,方法 接受(meth::Method,types::Tuple)::Bool 这里有一个测试集 using Base.Test @testset "accepts method checker" begin concrete = first(methods(length, (String,))) #length(s::String) in Base at strings/

目标是定义一个函数,该函数采用一个方法和一个类型元组, 并返回true。这些类型是该方法的有效输入。 非功能,
方法

接受(meth::Method,types::Tuple)::Bool

这里有一个测试集

using Base.Test
@testset "accepts method checker" begin
    concrete = first(methods(length, (String,)))
    #length(s::String) in Base at strings/string.jl:162

    abstract_ = last(collect(methods(length,(AbstractArray,))))
    #length(t::AbstractArray) in Base at abstractarray.jl:131

    triangular = first(methods(length, (StepRange,)))
    # length(r::StepRange{T,S} where S) where T<:Union{Int64, UInt64} in Base at range.jl:381

    a = "hello"
    a_t = (typeof(a),) #(String,)
    @test accepts(concrete, a_t)
    @test !accepts(abstract_, a_t)
    @test !accepts(triangular, a_t)

    b = 1.5:10
    b_t = (typeof(b),) #(StepRangeLen{Float64,Base.TwicePrecision{Float64},Base.TwicePrecision{Float64}})
    @test !accepts(concrete, b_t)
    @test accepts(abstract_, b_t)
    @test !accepts(triangular, b_t)

    c_t = (StepRange{Float64, Float64},) # Nothing real has this type as it can't be constructed
    @test !accepts(concrete, c_t)
    @test accepts(abstract_, c_t)
    @test !accepts(triangular, c_t)

    d = 1:2:10
    d_t = (typeof(d),) #(StepRange{Int64,Int64}
    @test !accepts(concrete, d_t)
    @test accepts(abstract_, d_t)
    @test accepts(triangular, d_t)
end
使用Base.Test
@测试集“接受方法检查器”开始
具体=第一个(方法(长度,(字符串,))
#strings/String.jl:162处的长度(s::String)
抽象=最后(收集(方法(长度,(抽象数组,))
#AbstractArray处的基长度(t::AbstractArray)。jl:131
三角形=第一个(方法(长度,(步长范围)

#长度(r::StepRange{T,S},其中S),其中T这是一个非常可怕的代码,但是:

function accepts(d::Method, ts::Tuple)
    ps = Base.unwrap_unionall(d.sig).parameters[2:end]
    length(ts) != length(ps) && return false

    all(zip(ts, ps)) do tp
        t, p = tp
        x = Base.rewrap_unionall(p, d.sig)
        Base.type_close_enough(x, t) || t <: x
    end
end
函数接受(d::方法,ts::元组)
ps=基本.展开所有(d.sig).参数[2:结束]
长度(ts)!=长度(ps)和返回值为假
所有(zip(ts,ps))都做tp
t、 p=tp
x=基础重新包装(p,d.sig)
基底。键入足够近的(x,t)| t