【问题标题】:How do I check if a given `Method` object accepts a given `Tuple` of types in Julia 0.6?如何检查给定的“方法”对象是否接受 Julia 0.6 中给定的类型的“元组”?
【发布时间】:2018-04-27 02:28:36
【问题描述】:

目标是定义一个接受方法和类型元组的函数, 并返回 true 这些类型是该方法的有效输入。 不起作用,method

accepts(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

由于 julia 没有太多的公共反射 API (as I have griped before),我可以接受可能会破坏每个补丁版本的代码

这个问题的目的是帮助我了解我需要做什么来更新InterfaceTesting.jl from 0.5 to 0.6的这一部分

使我的旧代码不再工作的原因是为了允许三角调度而引入的更改。 所以triangular 测试很难通过。

【问题讨论】:

    标签: reflection julia multiple-dispatch


    【解决方案1】:

    坦率地说,这是很吓人的代码,但是:

    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
    

    通过所有测试。 我不确定它是否遗漏了一些极端情况。 您在该元组中没有具有多种类型的测试。 基本上是从methodswith盗版的

    【讨论】:

      猜你喜欢
      • 2014-07-28
      • 2017-12-06
      • 2021-02-06
      • 2023-03-24
      • 2018-06-16
      • 2013-12-18
      • 2013-07-12
      • 1970-01-01
      • 2023-03-29
      相关资源
      最近更新 更多