Julia 中的表达式和宏
元编程是一种构建良好代码的方法。如果准确地使用这种技术,那么它可以产生更简洁和可读的代码。 Julia 是一种同音语言,这意味着 Julia 可以将自己的代码拟人化为语言本身的数据结构。程序可以在没有任何额外构建步骤的情况下重建自己的代码。作为元编程语言的 Julia 的另一个特性是运行程序能够动态地遇到自身特性的能力。表达式和宏是 Julia 元编程的重要组成部分。
Julia 中的表达式
表达式是 Julia 语言中的特殊类型对象。 Julia 代码似乎是从 Expr 类型的 Julia 数据结构扩展而来的语法树。这使得在 Julia 中设置和更改 Julia 代码变得简单,而无需推断原始文本。
任何尚未计算的代码块都可以说是一个表达式。有一个特定的函数用于评估表达式。
例如,
上面的代码只是形成了一个对象'Expr',除非任何函数对该对象采取行动,否则它将保持原样,例如eval() ,
这一切似乎有点复杂,因为您只需要添加两个数字。这个复杂表达式背后的原因是它向 Julia 程序员展示了新的强大功能。
表达式的创建
在 Julia 中有多种创建表达式的方法,下面列出了其中的一些:
使用 Expr()函数
Julia 提供了一个预定义的函数Expr(),可用于创建用户选择的表达式。
这里, my_exp = Expr(:(=), :x, 10)是语法的前缀符号,第一个参数是 head,其余是表达式的参数。头部确定要执行的操作,这里将值 10 分配给 x。
报价
使用引号创建表达式的基本语法是冒号( 🙂后跟括号()围绕代码的单个语句,即:()
您可以使用 Meta.parse 和 Expr 等各种其他方式构造此表达式a*b+c+10
使用报价...结束
这可以创建多行表达式。
插值
Julia 允许在表达式中插入字面量,即它允许将值插入到表达式中。
插入为表达式的元组示例,
注意:如果表达式没有被引用,它将显示编译时错误:
$ 只允许插入单个表达式,如果要插入多个表达式,请使用$(exps...),其中 exps 是表达式数组。
评估表达式
表达式可以使用预定义的eval()方法进行评估。
在上面的例子中, a的值在表达式的构造时被视为表达式中的中间值,因此a=0无关紧要。这里, a 的值被视为30 。
表达式上的函数
Julia 的一个非常有用的特性是能够在 Julia 内部生成和操作 Julia 代码。我们已经看到了一个返回 Expr 对象的函数示例:parse函数,它接受字符串Julia 代码并返回相应的 Expr。 Expr 对象也可以作为函数的参数,并且函数返回另一个 Expr 。这是一个例子,
Julia 中的宏
现在您知道了如何在 Julia 中处理表达式,现在有修改它们的步骤,这是使用宏完成的。宏是评估输入表达式并给出结果输出表达式的方法之一。 Julia 语言中的过程如下:它首先解析和评估宏,宏产生的处理后的代码最终像普通表达式一样被评估。宏可以称为代码的代码。下面是语法:
macro e(x)
if typeof(x) == Expr
println(x.args)
end
return x
end
使用字符“@”作为前缀运行宏,
@name exp1 exp2 ...
@name(exp1, exp2, ...)
这是两种写作风格,不应混用。
julia> @e 10
10
在传递数字“10”时,它会返回数字本身,因为数字不是表达式。以下是更多宏的示例。
示例 1:
示例 2:
有一些方法可以知道宏的参数。这可以使用宏体内的show()函数来完成:
让我们看一下@asset宏,下面是示例:
它可以按如下方式使用:
上面的代码其实是这样的:
10 == 10.0 ? nothing : throw(AssertionError("10 == 1.0"))
10 == 0 ? nothing : throw(AssertionError("10 == 0"))
整个表达式被放入发生@assert 宏调用的语法树中,然后在执行时,如果测试表达式的计算结果为真,则不返回任何内容,而如果测试为假,则会引发错误,指示断言那是错误的表达。
让我们看另一个宏@eval。您一定在考虑eval()但它们在某些方面有所不同。 eval()是一个函数,@eval 是一个宏。您熟悉 eval()函数,它首先扩展和评估表达式,但 @eval 不做同样的事情。它不会扩展表达式,如果要评估表达式,可以使用插值过程。这可以按如下方式完成:
基本上,
@eval $(ex) == eval(ex)
上面的代码块将返回 true。