具有全局函数的Julia码生成

具有全局函数的Julia码生成,julia,Julia,朱莉娅0.5.1 我想在引号内创建一个函数,该函数可以在使用指定宏后使用。这里有一个例子来说明我的意思 macro wat() quote type Foo end global bar() = begin end global function bar2() end type Baaz end end end @wat Foo() Baaz() bar() bar2() 现在当我运行这个程序时,最后一行崩溃了,因为bar2没有定义。我不明白为

朱莉娅0.5.1

我想在引号内创建一个函数,该函数可以在使用指定宏后使用。这里有一个例子来说明我的意思

macro wat()
  quote
    type Foo end
    global bar() = begin end
    global function bar2()
    end
    type Baaz end
  end
end

@wat
Foo()
Baaz()
bar()
bar2()
现在当我运行这个程序时,最后一行崩溃了,因为bar2没有定义。我不明白为什么,因为在我的理解中,bar()和bar2()应该相等,而bar只是bar2的语法糖。但它们显然是不平等的,我不明白为什么一个有效,另一个无效

第二,有没有一种方法可以在引用中定义bar和bar2,而不使用全局关键字,并且在宏执行后仍然可用

我想要使用bar2符号的动机是,我可以用这种语法指定返回类型

global bar3()::Void = begin end

不允许使用语法。

在Julia宏的返回表达式中,局部变量的名称替换为唯一符号:

julia> macro foo()
        quote
            x = 1
            global y = 2
        end
    end
@foo (macro with 1 method)

julia> macroexpand(:(@foo))
quote  # REPL[1], line 4:
    #1#x = 1
    global y = 2
end
调用此功能可避免在调用站点与变量发生意外冲突

要避免这种行为,必须使用
esc

julia> macro bar()
                quote
                    x = 1
                end |> esc
            end
@bar (macro with 1 method)

julia> macroexpand(:(@bar))
quote  # REPL[1], line 3:
    x = 1
end
通常,我们不想转义整个返回的表达式,而只想转义其中的特定部分:

julia> macro myshow(expr)
        quote
            x = $(esc(expr))
            println($(string(expr)), " = ", x)
            x
        end
    end
@myshow (macro with 1 method)

julia> x = pi/2
1.5707963267948966

julia> macroexpand(:(@myshow sin(x)))
quote  # REPL[1], line 3:
    #1#x = sin(x) # REPL[1], line 4:
    (Main.println)("sin(x)", " = ", #1#x) # REPL[1], line 5:
    #1#x
end

julia> @myshow sin(x)
sin(x) = 1.0
1.0

julia> x
1.5707963267948966

有关详细信息,我建议阅读手册中的。

由于宏卫生(),返回表达式中的局部变量名称将替换为唯一符号。因此,您需要对带有局部变量的符号或表达式使用
esc
,这些变量应该单独使用。但是,我不确定为什么
global
不适用于
bar2
。使用
macroexpand(:(@wat))
查看生成的代码。macroexpand向我显示,某些符号已添加到bar2函数中。它看起来像是
global function#3bar2()…
这个
bar()
函数周围没有这种东西。但是我怎样才能防止朱莉娅在我的函数中添加一些垃圾呢?@tim在引用中加入esc就可以了,如果你愿意的话,你可以回答。否则我明天会用你的答案回答自己;)与这个问题无关,当你说崩溃时,它表明系统出现异常,导致Julia崩溃——非常糟糕。最好说最后一行出现了错误,或者抛出了异常