#

一、宏基础 #

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!

七、总结 #

本章我们学习了:

  1. 宏定义:macro关键字
  2. 卫生宏:变量捕获和esc
  3. 常用宏:@show、@time、@assert
  4. 宏实践:计时、重试、日志
  5. 宏与函数:选择建议

接下来让我们学习Julia的代码生成!

最后更新:2026-03-27