macros - 如何在 julia 中创建多行宏?

标签 macros julia metaprogramming

macro Estruct(name,arg,type,max=100,min=0,descritpion="")
        :(struct $(esc(name))
        $((esc(arg)))
        $(esc(name))($(esc(arg)))=new(
          check($(esc(type)),$(esc(arg)),$(esc(name)),$(esc(max)),$(esc(min)),$(esc(descritpion))))
       end)
end

我怎样才能像这样使用这个宏:

@Estruct begin
    B 
    arg1 
    Float64 
    200.0 
    5.0 
    "this"
end

我不知道如何制作多行宏。我以为我只需要添加开始和结束,但我总是得到:MethodError: no method matching var"@Estruct"(::LineNumberNode,::Module,::Expr)

最佳答案

没有多行宏这样的东西,它只是一个以 block 作为参数的宏。您可以通过编写仅返回其参数的虚拟版本来查看宏是如何被调用的:

macro Estruct(args...); args; end

现在您可以按照您想要的方式调用它,它会将其参数作为元组返回:

julia> args = @Estruct begin
           B
           arg1
           Float64
           200.0
           5.0
           "this"
       end
(quote
    #= REPL[12]:2 =#
    B
    #= REPL[12]:3 =#
    arg1
    #= REPL[12]:4 =#
    Float64
    #= REPL[12]:5 =#
    200.0
    #= REPL[12]:6 =#
    5.0
    #= REPL[12]:7 =#
    "this"
end,)


julia> typeof(args)
Tuple{Expr}

julia> dump(args[1])
Expr
  head: Symbol block
  args: Array{Any}((12,))
    1: LineNumberNode
      line: Int64 2
      file: Symbol REPL[12]
    2: Symbol B
    3: LineNumberNode
      line: Int64 3
      file: Symbol REPL[12]
    4: Symbol arg1
    5: LineNumberNode
      line: Int64 4
      file: Symbol REPL[12]
    ...
    8: Float64 200.0
    9: LineNumberNode
      line: Int64 6
      file: Symbol REPL[12]
    10: Float64 5.0
    11: LineNumberNode
      line: Int64 7
      file: Symbol REPL[12]
    12: String "this"

julia> args[1].args
12-element Vector{Any}:
    :(#= REPL[12]:2 =#)
    :B
    :(#= REPL[12]:3 =#)
    :arg1
    :(#= REPL[12]:4 =#)
    :Float64
    :(#= REPL[12]:5 =#)
 200.0
    :(#= REPL[12]:6 =#)
   5.0
    :(#= REPL[12]:7 =#)
    "this"

这告诉您宏被调用时带有一个参数,该参数是一个头类型为 :blockExpr,即一个参数是一个带引号的 block 。要实现您的“多行宏”,您需要实现宏主体以接受引用的 block 表达式并对其进行处理,大概是通过查看其 .args 字段,这是您感兴趣的所有表达式的位置是。您可能希望忽略其中的所有 LineNumberNode 对象,只处理 block 中的其他项目。

关于macros - 如何在 julia 中创建多行宏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/69555092/

相关文章:

c++ - __COUNTER__ 宏是否可移植?

julia - 如何在anaconda环境中安装Julia?

math - 添加导致 `MethodError: no method matching +(::Array{Int64, 0},::Int64)`

javascript - CoffeeScript 类和 nosuchmethod

ruby - 重新初始化 ruby​​ 类

formatting - 不在 sympy 的 `printing.ccode` 方法中将 X*X*X 收缩为 pow(X,3)

C++11 自动转换

c - 禁止 C 预处理器在另一个中使用宏

c - 了解宏行为和原线程

julia - 如果值为正则打印额外的空格