如何在Julia中查找和替换AST的子表达式

如何在Julia中查找和替换AST的子表达式,julia,metaprogramming,Julia,Metaprogramming,假设我有一个类似于的表达式:(Main.I/(0.5*Main.I*sin(Main.I)) 我想将每次出现的Main.I替换为其他符号。在Julia中是否有一种惯用的方法来执行此操作?Main.I不是一个符号,而是一个表达式,您可以通过执行转储(:(Main.I))来检查它 下面是一个我认为可能符合您需要的快速书写: function expr_replace(expr, old, new) expr == old && return new if expr i

假设我有一个类似于
的表达式:(Main.I/(0.5*Main.I*sin(Main.I))


我想将每次出现的
Main.I
替换为其他符号。在Julia中是否有一种惯用的方法来执行此操作?

Main.I
不是一个符号,而是一个表达式,您可以通过执行
转储(:(Main.I))
来检查它

下面是一个我认为可能符合您需要的快速书写:

function expr_replace(expr, old, new)
    expr == old && return new
    if expr isa Expr
        expr = deepcopy(expr) # to avoid mutation of source
        for i in eachindex(expr.args)
            expr.args[i] = expr_replace(expr.args[i], old, new)
        end
    end
    expr
end
对你有用吗

编辑:这是一个对
deepcopy
进行最低限度安全使用的版本:

function expr_replace(expr, old, new)
    function f(expr)
        expr == old && return deepcopy(new)
        if expr isa Expr
            for i in eachindex(expr.args)
                expr.args[i] = f(expr.args[i])
            end
        end
        expr
    end

    f(deepcopy(expr))
end

一般来说,我想这并不重要,因为您可能不想通过此函数传递100行代码。

这不会做很多不必要的
deepcopy
s吗?是的,我将其视为显示正在发生的事情的一种方式。我将编写第二个版本,避免过多使用
deepcopy