消除Julia元编程中的各种引用机制的歧义

P i*_*P i 8 metaprogramming quoting julia

有人可以清楚地列出Julia中可用于元编程的各种引用机制,并以最小的例子说明每一个吗?

因此很清楚在哪种情况下使用哪种...

据我所知,有:

  • :(someExpr; maybeMore)
  • quote; ...expressions... end; 这与上面几乎相同,仅用于调试目的的行号
  • Expr(:quote, x)其中(根据@totalverb)相当于Meta.quot(x)
  • QuoteNode(根据Jeff Bezanson所说)"仅用于内部AST表示,而不是宏.除非你在编译器的后期工作,否则可以安全地忽略."

这份清单是否全面?我错过了任何其他陈述吗?

phi*_*icr 8

:...是默认的报价机制.它解析表达式并返回AST.

:x == Symbol("x")

:(x + y) == Expr(:call, :+, :x, :y)

:(x; y; z) == Expr(:block, :x, :y, :z)
Run Code Online (Sandbox Code Playgroud)

eval(:<expr>)应该返回与just相同的<expr>(假设<expr>是当前全局空间中的有效表达式)

eval(:(1 + 2)) == 1 + 2

eval(:(let x=1; x + 1 end)) == let x=1; x + 1 end
Run Code Online (Sandbox Code Playgroud)

quote ... end 是相同的 :(begin ... end)


Expr(:quote, x) 用于表示引号内的引号.

Expr(:quote, :(x + y)) == :(:(x + y))

Expr(:quote, Expr(:$, :x)) == :(:($x))
Run Code Online (Sandbox Code Playgroud)

QuoteNode(x)类似Expr(:quote, x)但它可以防止插值.

eval(Expr(:quote, Expr(:$, 1))) == 1

eval(QuoteNode(Expr(:$, 1))) == Expr(:$, 1)
Run Code Online (Sandbox Code Playgroud)

这是一个使用所有这些宏的宏:

macro quoted(expression)
    quote
        println("received expression: :(", $(QuoteNode(expression)), ")")
        $(Expr(:quote, expression))
    end
end
Run Code Online (Sandbox Code Playgroud)

用法:

julia> x = 1
1

julia> @quoted $x + 1
received expression: :($(Expr(:$, :x)) + 1)
:(1 + 1)

julia> @quoted :(x + 1)
received expression: :($(Expr(:quote, :(x + 1))))
:($(Expr(:quote, :(x + 1))))
Run Code Online (Sandbox Code Playgroud)

编辑:Meta.quot(x)确实是一样的Expr(:quote, x).它没有文档,在任何地方都没有提到,但它是对Base(https://github.com/JuliaLang/julia/pull/1755)导出的函数的有意识的补充,我还没有看到任何弃用它的计划,所以你可以用它.