TLDR: @
调用宏。https://docs.julialang.org/en/v1/manual/metaprogramming/
在我看来,Julia 的最佳特性之一就是其宏。它们允许您轻松编写操作源代码的函数。例如,@.
将 0.3 * sin(fr * xs - ph)
转换为 0.3 .* sin(fr .* xs - ph)
。另一个常见的例子是 @time
,它大致将相同的表达式转换为
t1=time()
0.3 * sin(fr * xs - ph)
println(time()-t1)
我认为值得补充的是,通过调用帮助命令可以很容易地学习@.
的作用。按下?
键然后键入@.
并按回车键即可获得以下信息:
help?> @.
@. expr
Convert every function call or operator in expr into a "dot call" (e.g.
convert f(x) to f.(x)), and convert every assignment in expr to a "dot
assignment" (e.g. convert += to .+=).
If you want to avoid adding dots for selected function calls in expr, splice
those function calls in with $. For example, @. sqrt(abs($sort(x))) is
equivalent to sqrt.(abs.(sort(x))) (no dot for sort).
(@. is equivalent to a call to @__dot__.)
Examples
≡≡≡≡≡≡≡≡≡≡
julia> x = 1.0:3.0; y = similar(x);
julia> @. y = x + 3 * sin(x)
3-element Array{Float64,1}:
3.5244129544236893
4.727892280477045
3.4233600241796016
在这里,你还会学到@.
只是@__dot__
的简写。
如果你想找到它的定义,可以写例如:
julia> @which @. 1
@__dot__(__source__::LineNumberNode, __module__::Module, x) in Base.Broadcast at broadcast.jl:1241
要获得其实现位置的确切信息,或者写下@edit @. 1
,它将在您的编辑器中打开。
上面我已经解释了如何学习@.
的作用和实现方式。如果你想学习@.
(或者任何宏)的效果,你可以使用@macroexpand
宏。因此,如果你写入:
julia> @macroexpand @. coalesce(sin(@view x[:, 1]), 0.0)
:(coalesce.(sin.(true && (view)(x, :, 1)), 0.0))
您可以看到@.
宏如何重写您的原始表达式coalesce(sin(x), 0.0)
。请注意,在这种情况下,表达式未被评估 - 您只会得到一个等价表达式,其中所有宏已被删除。
如果您只想查看@.
宏展开(假设 - 如上面的示例中一样 - 它是最外层的宏),则使用:
julia> @macroexpand1 @. coalesce(sin(@view x[:, 1]), 0.0)
:(coalesce.(sin.(#= REPL[11]:1 =# @view(x[:, 1])), 0.0))
@macroexpand1
不是递归的,仅展开最外层的宏,而保留了@view
宏不受影响。
@macroexpand1
也可以吗? - Frames Catherine White