julia学习笔记:元编程-宏(macro)

宏像是一个函数,这个函数接受一组参数返回一个表达式。
一个简单的宏定义:

julia> macro sayhello(name)
           return :( println("Hello, ", $name) )
       end
@sayhello (macro with 1 method)

这个宏接收一个参数并返回一个表达式打印一句话,调用:

julia> @sayhello("human")
Hello, human

1、宏调用


两种调用方式

@name expr1 expr2 ...
@name(expr1, expr2, ...)

注意第二种与下面带空格的调用的区别,下面的调用表示传一个参数,这个参数是一个元组;而上面第二种调用表示传递多个参数以逗号分隔:

@name (expr1, expr2, ...)

1)数组做参数

@name[a b] * v
@name([a b]) * v

注意和下面的区别,上面表示数组做[a b]参数调用宏然后乘以v ,下面的表示数组[a b]先和v相乘,结果作为宏的参数:

@name [a b] * v

2)宏除了手动传递的参数外,还有隐含传递的参数__source__ 和 __module__,__source__提供的宏调用的位置信息,用于排查错误;如图:图片描述

2、构造高级宏


下面定义一个简单的宏@assert,这个宏用来判断传入表达式的值,如果是true返回nothing,否则报错。
Note:报错信息是将传入的表达式转换成字符串,这个无法用函数实现。

julia> macro assert(ex)
           return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )
       end
@assert (macro with 1 method)

这样调用:

julia> @assert 1 == 1.0

julia> @assert 1 == 0
ERROR: AssertionError: 1 == 0

上面的调用等同于下面的表达式:

1 == 1.0 ? nothing : throw(AssertionError("1 == 1.0"))
1 == 0 ? nothing : throw(AssertionError("1 == 0"))

下面我们把宏扩展一下,使其有一个传入报错信息的参数:

julia> macro assert(ex, msgs...)
           msg_body = isempty(msgs) ? ex : msgs[1]
           msg = string(msg_body)
           return :($ex ? nothing : throw(AssertionError($msg)))
       end
@assert (macro with 1 method)

注意:宏也是一个函数,所以宏可以有多个方法,如下面的宏有两个方法:

julia> macro assert(ex)
                  return :( $ex ? nothing : throw(AssertionError($(string(ex)))) )
                         end
@assert (macro with 2 methods)

使用@macroexpand查看宏扩展后的结果:

julia> @macroexpand @assert a == b
:(if Main.a == Main.b
        Main.nothing
    else
        (Main.throw)((Main.AssertionError)("a == b"))
    end)
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值