宏 #
一、宏基础 #
1.1 定义宏 #
julia
macro sayhi(name)
return :(println("Hello, ", $name, "!"))
end
@sayhi "Julia"
1.2 宏参数 #
julia
macro twice(ex)
return quote
$ex
$ex
end
end
@twice println("Hello")
1.3 宏展开 #
julia
macroexpand(@__MODULE__, :(@sayhi "Julia"))
二、卫生宏 #
2.1 卫生性 #
宏不会意外捕获外部变量:
julia
macro set_x(value)
:(x = $value)
end
x = 10
@set_x 20
x
2.2 esc函数 #
使用esc转义表达式:
julia
macro set_var(var, value)
:($(esc(var)) = $value)
end
y = 10
@set_var y 20
y
2.3 gensym #
生成唯一符号:
julia
macro safe_swap(a, b)
temp = gensym(:temp)
quote
$temp = $(esc(a))
$(esc(a)) = $(esc(b))
$(esc(b)) = $temp
end
end
x, y = 1, 2
@safe_swap x y
(x, y)
三、常用宏 #
3.1 @show #
julia
x = 10
@show x + 1
3.2 @time #
julia
@time sleep(1)
3.3 @assert #
julia
@assert 1 + 1 == 2
3.4 @enum #
julia
@enum Color Red Green Blue
Red
Green
3.5 @simd #
julia
function sum_simd(arr)
total = 0.0
@simd for x in arr
total += x
end
total
end
四、宏实践 #
4.1 计时宏 #
julia
macro timed(ex)
quote
local start = time()
local result = $(esc(ex))
local elapsed = time() - start
println("Elapsed: ", elapsed, " seconds")
result
end
end
@timed sleep(1)
4.2 重试宏 #
julia
macro retry(n, ex)
quote
local attempts = 0
local result
while attempts < $n
attempts += 1
try
result = $(esc(ex))
break
catch e
if attempts == $n
rethrow()
end
end
end
result
end
end
@retry 3 rand() > 0.9 ? error("fail") : "success"
4.3 日志宏 #
julia
macro log(level, msg)
quote
println("[", $(string(level)), "] ", $msg)
end
end
@log INFO "Application started"
@log DEBUG "Processing data"
4.4 缓存宏 #
julia
macro cached(ex)
cache_name = Symbol(:_cache_, ex)
quote
if !isdefined(@__MODULE__, $(QuoteNode(cache_name)))
$(esc(cache_name)) = $(esc(ex))
end
$(esc(cache_name))
end
end
@cached expensive_computation() = begin
println("Computing...")
sleep(1)
42
end
五、宏与函数的区别 #
5.1 执行时机 #
- 宏:编译时展开
- 函数:运行时执行
5.2 参数处理 #
- 宏:接收表达式
- 函数:接收值
5.3 选择建议 #
- 需要操作代码结构时使用宏
- 其他情况使用函数
六、实践练习 #
6.1 练习1:断言宏 #
julia
macro check(condition, message="")
quote
if !$(esc(condition))
error("Check failed: ", $(string(condition)), " ", $message)
end
end
end
@check 1 + 1 == 2
@check 1 + 1 == 3 "Math is broken"
6.2 练习2:单例宏 #
julia
macro singleton(name, ex)
quote
$(esc(name))() = begin
if !isdefined(@__MODULE__, :_singleton_instance)
global _singleton_instance = $(esc(ex))
end
_singleton_instance
end
end
end
@singleton config Dict("host" => "localhost")
config()
6.3 练习3:委托宏 #
julia
macro delegate(source, methods)
code = Expr(:block)
for method in methods.args
push!(code.args, quote
$method(args...) = $method($(esc(source)), args...)
end)
end
return code
end
struct Wrapper
data::Vector{Int}
end
@delegate wrapper.data length push!
七、总结 #
本章我们学习了:
- 宏定义:macro关键字
- 卫生宏:变量捕获和esc
- 常用宏:@show、@time、@assert
- 宏实践:计时、重试、日志
- 宏与函数:选择建议
接下来让我们学习Julia的代码生成!
最后更新:2026-03-27