例如,这里:
ys = lift(frequency, phase) do fr, ph
@. 0.3 * sin(fr * xs - ph)
end
Run Code Online (Sandbox Code Playgroud)
从这里。
我未能将其解释为宏定义或调用。
我认为值得补充的是,@.
通过调用帮助很容易了解其作用。按?
然后写入@.
并按 Enter 键即可获取:
help?> @.\n @. expr\n\n Convert every function call or operator in expr into a "dot call" (e.g.\n convert f(x) to f.(x)), and convert every assignment in expr to a "dot\n assignment" (e.g. convert += to .+=).\n\n If you want to avoid adding dots for selected function calls in expr, splice\n those function calls in with $. For example, @. sqrt(abs($sort(x))) is\n equivalent to sqrt.(abs.(sort(x))) (no dot for sort).\n\n (@. is equivalent to a call to @__dot__.)\n\n Examples\n \xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\xe2\x89\xa1\n\n julia> x = 1.0:3.0; y = similar(x);\n \n julia> @. y = x + 3 * sin(x)\n 3-element Array{Float64,1}:\n 3.5244129544236893\n 4.727892280477045\n 3.4233600241796016\n
Run Code Online (Sandbox Code Playgroud)\n您还可以在其中了解到这@.
只是 的简写@__dot__
。
如果你想找到它的定义,请写下:
\njulia> @which @. 1\n@__dot__(__source__::LineNumberNode, __module__::Module, x) in Base.Broadcast at broadcast.jl:1241\n
Run Code Online (Sandbox Code Playgroud)\n获取有关其实现或写入位置的确切信息@edit @. 1
,它将在您的编辑器中打开。
上面我已经评论了如何学习它的@.
作用以及它是如何实现的。@.
如果您想了解(或任何一般宏)的效果,您可以使用该@macroexpand
宏。因此,如果你写例如:
julia> @macroexpand @. coalesce(sin(@view x[:, 1]), 0.0)\n:(coalesce.(sin.(true && (view)(x, :, 1)), 0.0))\n
Run Code Online (Sandbox Code Playgroud)\n你可以看到@.
宏如何重写你的原始表达式coalesce(sin(x), 0.0)
。请注意,在这种情况下,不会计算表达式 - 您只会得到删除所有宏的等效表达式。
如果你只想看@.
扩展的宏(假设 - 如上面的示例所示,它是最外面的宏),则使用:
julia> @macroexpand1 @. coalesce(sin(@view x[:, 1]), 0.0)\n:(coalesce.(sin.(#= REPL[11]:1 =# @view(x[:, 1])), 0.0))\n
Run Code Online (Sandbox Code Playgroud)\n正如您所看到的,@macroexpand1
它不是递归的,仅扩展了最外面的宏,并且使@view
宏保持不变。
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)
Run Code Online (Sandbox Code Playgroud)
请注意,这些都不是由函数实现的,因为函数在运行之前会对其输入进行评估,而宏则对代码本身进行操作。