module - 为模块中的每个子类型生成一个方法
问题描述
(从 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
解决方案
来自 Julia slack 的 Mason Protter:
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 将继续使用旧版本模块中导出的函数。
推荐阅读
- iot - IoT 代理配置
- python - 是否可以循环 10^8 种可能性来确定正确答案?
- java - 配置问题:找不到 XML 模式命名空间的 Spring NamespaceHandler
- node.js - 为 Node 模块导入 TS 类型
- angularjs - 带有引导崩溃的嵌套 ng-repeats,$index 和 ng-init 的问题
- javascript - 复制到剪贴板时如何添加新行
- javascript - 我想在 Object 中返回异步函数的值
- google-apps-script - 用户无权调用 showModalDialog()
- hive - 使用 sqoop 将数据从 CSV 导入 Avro 表的命令
- android - Android - 运行时的 Dagger 注入