macros - 将字符串内插值传递给宏

标签 macros julia

我对这段代码的问题是当传递内插字符串时宏失败:

macro t(a, b, c)
    quote
        println(:c, " = " , $c)
        ($a, $b, $c)
    end
end

function test()
    # works:
    @t 1 2 3

    # doesn't work:
    x = π
    @t 1 2 "x is $x"
end

test()
test()
c = 3   # works
ERROR: UndefVarError: x not defined

所以里面t插值 x值不可用。有没有解决方案,或者在这里使用宏只是一个坏主意?

最佳答案

为了实现你想要的,你需要使用 esc :

macro t(a, b, c)
    quote
        local a1 = $(esc(a))
        local b1 = $(esc(b))
        local c1 = $(esc(c))
        println(:c, " = ", c1)
        (a1, b1, c1)
    end
end

请注意,我定义了变量 a1 , b1 , 和 c1一次,然后重复使用它们。原因是,如果你写了这样的东西:
macro t(a, b, c)
    quote
        println(:c, " = ", $(esc(c)))
        ($(esc(a)), $(esc(b)), $(esc(c)))
    end
end

这是很自然的(或者可能不是:)),你会遇到问题 c将被评估两次,例如。在这个例子中:
julia> macro t(a, b, c)
           quote
               println(:c, " = ", $(esc(c)))
               ($(esc(a)), $(esc(b)), $(esc(c)))
           end
       end
@t (macro with 1 method)

julia> function test()
           @t 1 2 rand()
       end
test (generic function with 1 method)

julia> test()
c = 0.03771143425073453
(1, 2, 0.1819496773810383)

请注意,将打印不同的值并返回不同的值。这个问题存在于您的原始宏中(即使它使用了@Bill 指出的全局变量):
julia> macro t(a, b, c)
           quote
               println(:c, " = " , $c)
               ($a, $b, $c)
           end
       end
@t (macro with 1 method)

julia> @t 1 2 rand()
c = 0.7021554643798531
(1, 2, 0.6363717837673994)

总的来说,我认为 @code_lowered@macroexpand当您使用元编程调试代码时,宏对您很有用。

关于macros - 将字符串内插值传递给宏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59799398/

相关文章:

c++ - 宏有什么好的用途吗?

c++ - C/C++ 宏扩展与代码生成

docker - 使用 docker 的 Julia 集群

c - C预处理器中的嵌套##运算符

c - 使用##连接宏常量

indentation - 为什么 Julia 不像 Python 那样基于缩进?

multithreading - 为什么我在 Julia 的并行化 for 循环中观察不到 speedo

julia - Plots.jl 添加趋势线,并更改 x 轴

arrays - 在 julia 中合并两个排序数组

arrays - 如何将一组 Expr(表达式)传递给 Haxe 宏?