表达式 #

一、表达式基础 #

1.1 Expr类型 #

julia
ex = :(1 + 2)
typeof(ex)
ex.head
ex.args

1.2 创建表达式 #

julia
ex1 = :(a + b)
ex2 = Expr(:call, :+, :a, :b)
ex3 = parse("a + b")

1.3 表达式结构 #

julia
ex = :(f(x, y))
ex.head
ex.args

二、引用表达式 #

2.1 :() 语法 #

julia
ex = :(1 + 2 * 3)

2.2 quote … end #

julia
ex = quote
    x = 1
    y = 2
    x + y
end

2.3 插值 #

julia
x = 10
ex = :($x + 2)

y = :z
ex = :($y = 10)

2.4 嵌套引用 #

julia
ex = :(:(1 + 2))

三、表达式操作 #

3.1 遍历表达式 #

julia
function traverse(ex::Expr)
    println("Head: ", ex.head)
    for arg in ex.args
        if arg isa Expr
            traverse(arg)
        else
            println("  Arg: ", arg)
        end
    end
end

traverse(:(1 + 2 * 3))

3.2 修改表达式 #

julia
function replace_symbols(ex::Expr, mapping)
    for i in eachindex(ex.args)
        arg = ex.args[i]
        if arg isa Symbol && haskey(mapping, arg)
            ex.args[i] = mapping[arg]
        elseif arg isa Expr
            replace_symbols(arg, mapping)
        end
    end
    return ex
end

ex = :(a + b)
replace_symbols(ex, Dict(:a => :x, :b => :y))

3.3 表达式匹配 #

julia
function match_call(ex, func)
    ex isa Expr && ex.head == :call && ex.args[1] == func
end

ex = :(f(x, y))
match_call(ex, :f)

四、表达式求值 #

4.1 eval #

julia
ex = :(1 + 2)
eval(ex)

x = 10
ex = :(x * 2)
eval(ex)

4.2 在模块中求值 #

julia
module MyModule
    x = 10
end

ex = :(x)
eval(MyModule, ex)

4.3 安全求值 #

julia
function safe_eval(ex)
    try
        eval(ex)
    catch e
        println("Error: $e")
        nothing
    end
end

五、表达式类型 #

5.1 常见head类型 #

head 描述
:call 函数调用
:ref 索引访问
:(=) 赋值
:block 代码块
:if 条件语句
:for for循环
:while while循环
:function 函数定义
:macrocall 宏调用

5.2 示例 #

julia
dump(:(f(x)))
dump(:(a[i]))
dump(:(x = 1))
dump(quote
    x = 1
    y = 2
end)

六、实践练习 #

6.1 练习1:表达式计数 #

julia
function count_calls(ex::Expr, func)
    count = 0
    if ex.head == :call && ex.args[1] == func
        count += 1
    end
    for arg in ex.args
        if arg isa Expr
            count += count_calls(arg, func)
        end
    end
    return count
end

ex = :(f(f(x), f(y, f(z))))
count_calls(ex, :f)

6.2 练习2:表达式简化 #

julia
function simplify(ex::Expr)
    if ex.head == :call && ex.args[1] == :+
        if ex.args[2] == 0
            return simplify(ex.args[3])
        elseif ex.args[3] == 0
            return simplify(ex.args[2])
        end
    end
    return ex
end

simplify(:(0 + x))
simplify(:(x + 0))

6.3 练习3:代码生成 #

julia
function generate_loop(var, start, stop, body)
    quote
        for $var in $start:$stop
            $body
        end
    end
end

ex = generate_loop(:i, 1, 10, :(println(i)))
eval(ex)

七、总结 #

本章我们学习了:

  1. Expr类型:表达式结构
  2. 引用表达式::()和quote
  3. 表达式操作:遍历和修改
  4. 表达式求值:eval函数
  5. 表达式类型:常见head类型

接下来让我们学习Julia的宏!

最后更新:2026-03-27