【问题标题】:Generating a method for each subtype within a module为模块中的每个子类型生成方法
【发布时间】:2020-02-14 18:07:45
【问题描述】:

(从 Julia slack 转发给后代)

假设我有一些常量,例如

const FooConst = 1
const BarConst = 2

我也有一些结构

struct Foo end
struct Bar end

我现在想为每个结构定义一个方法来查找该常量

f(::Type{Foo}) = FooConst
f(::Type{Bar}) = BarConst

如何使用元编程实现最后一个块?我实际上是在尝试将 Const 添加到 Struct 名称的末尾并在代码中查找

...

...(this) 在模块之外工作,但在我的模块中,常量不会被导出。导入模块后, f 无法查找常量。 MWE在这里:

module M
import InteractiveUtils: subtypes
export Foo, Bar, f

abstract type Super end
struct Foo <: Super end
struct Bar <: Super end

const FooConst = 1
const BarConst = 2

for T in subtypes(Super)
    @eval f(::Type{$T}) = $(Symbol(T, "Const"))
end

end # module

然后在我的 REPL 中:

julia> using Main.M
julia> f(Foo)
ERROR: UndefVarError: Main.M.FooConst not defined
Stacktrace:
 [1] f(::Type{Foo}) at ./none:11
 [2] top-level scope at none:0

但是我可以直接访问它:

julia> Main.M.FooConst
1

【问题讨论】:

    标签: module julia metaprogramming


    【解决方案1】:

    来自 Julia slack 的 Mason Protter:

    梅森·普罗特下午 2:26 @Sebastian Rollen 问题是Symbol(T, "const")。这实际上最终扩展到Symbol("Main.Foo.FooConst")Symbol("Main.Foo.BarConst"),而不是分别为Symbol("FooConst")Symbol("BarConst")。您可以使用Symbol(nameof(T), "Const") 修复该问题,如下所示:

    module M
    import InteractiveUtils: subtypes
    export Foo, Bar, f
    
    abstract type Super end
    struct Foo <: Super end
    struct Bar <: Super end
    
    const FooConst = 1
    const BarConst = 2
    
    for T in subtypes(Super)
        @eval f(::Type{$T}) = $(Symbol(nameof(T), "Const"))
    end
    
    end # module
    
    julia> using .M;  f(Foo)
    1
    
    julia> f(Bar)
    2
    

    确保在运行此代码之前重新启动 Julia,否则 Julia 将继续使用旧版本模块中导出的函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-23
      • 2011-07-05
      • 2015-06-23
      • 2021-04-19
      • 2021-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多