如何将变量值传递给julia中的宏?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何将变量值传递给julia中的宏?相关的知识,希望对你有一定的参考价值。

我想将变量的值传递给julia中的宏?我尝试了以下但它不起作用:

macro m(a,b)
  @show a,b
  ex = quote
    $a = eval($b)
  end
  @show ex
  esc(ex)
end

b = 1
@m a $b

输出:

(a, b) = (:a, :($(Expr(:$, :b))))
ex = quote  # REPL[20], line 4:
    a = eval($(Expr(:$, :b)))
end
ERROR: unsupported or misplaced expression $
答案

你非常接近! :)

宏也可以有类型注释,它们是在编译时工作的函数,但它们的输入只能是Exprs,Symbols或常量值,即:Int,宏在调用之前不评估它们的输入,就像调用之前的函数一样,宏在语法上工作。

julia> macro m(a::Symbol, b)  # in ths method a should allways be a symbol
           # use spaces and parens as needed to delimit and 
           # group args as needed, not commas in this case
           @show a b          # or use this: @show(a, b) notice comma here
           ex = quote         # there is no need to use eval here a macro
               $a = $b        # will compile and evaluate the returning
           end                # expression when invoked
           @show ex
           return esc(ex)     # esc will use surrounding scope instead of gensyms
       end
@m (macro with 1 method)

不要在宏的主体内部使用eval,在这种情况下它位于返回表达式的主体中(有时可能需要这样,但这不是其中之一)。

julia> x = 2
2

老实说我还不知道如何使插件类似于像@evalBenchmarkTools.@btime工作的宏(应该在手册中解释,我将不得不研究那些宏的代码),但是在调用宏时你不需要$这是一个简单的例子。

julia> @m y (x + 1)  # parens for grouping, or @m(y, x + 1)
a = :y               # :y is a symbol
b = :(x + 1)
ex = quote
    #= REPL[17]:4 =#
    y = x + 1
end
3

如果你不使用esc,它将卫生地创建gensyms,在这种情况下,它使用周围的范围变量。

julia> @m z rand(x, y)
a = :z
b = :(rand(x, y))
ex = quote
    #= REPL[17]:4 =#
    z = rand(x, y)
end
2×3 Array{Float64,2}:
 0.817233  0.623775  0.277464
 0.421573  0.443654  0.296359

gensyms看起来像这样:

julia> gensym(:foo)
Symbol("##foo#924")

以上是关于如何将变量值传递给julia中的宏?的主要内容,如果未能解决你的问题,请参考以下文章

如何将变量值从一个文件中的一个类传递给另一个文件中的另一个类python tkinter

通过单击鼠标将变量值传递给java中的servlet

将变量值从 JS 传递给 PHP

如何将变量值传递给套接字字符串

将变量值传递给 paypal API - first_name 和 last_name

将变量值分配给模板中的表单域