具有全局函数的Julia码生成
朱莉娅0.5.1 我想在引号内创建一个函数,该函数可以在使用指定宏后使用。这里有一个例子来说明我的意思具有全局函数的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没有定义。我不明白为
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崩溃——非常糟糕。最好说最后一行出现了错误,或者抛出了异常