📜  Julia 中的表达式和宏

📅  最后修改于: 2022-05-13 01:54:31.026000             🧑  作者: Mango

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。