是否可以在一行上使用多个宏?

时间:2014-08-22 23:19:12

标签: macros julia callstack

有没有人知道是否可以为一行使用多个宏?例如,

@devec, @inbounds [expr]

1 个答案:

答案 0 :(得分:4)

Yes, you can, since:

  

宏是表达式生成函数的类比   编译时间。正如函数将参数值的元组映射到a   返回值,宏将参数表达式的元组映射到返回的   表达。使用以下通用语法调用宏:

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

这是一个利用两个众所周知的宏的例子(尽管有点荒谬):

# This is an assert construct very similar to what you'd find in a language like
# C, C++, or Python. (This is slightly modified from the example shown in docs)
macro assert(ex)
    return :($ex ? println("Assertion passed") # To show us that `@assert` worked
                 : error("Assertion failed: ", $(string(ex))))
end

# This does exactly what you expect to: time the execution of a piece of code
macro timeit(ex)
    quote
        local t0 = time()
        local val = $ex
        local t1 = time()
        println("elapsed time: ", t1-t0, " seconds")
        val
    end
end

但是,请注意这两个成功的(即 - 不要抛出任何错误)宏调用:

@assert factorial(5)>=0
@timeit factorial(5)

而且,现在在一起:

@timeit @assert factorial(5)>=0

因为最右边的宏没有引发错误,所以上面的行返回执行factorial(5)所花费的总时间以及执行断言的时间。

但是,需要注意的重要一点是当其中一个宏发生故障时,调用堆栈中其他宏的执行当然会被终止(应该是这样):

# This will throw an error (because we explicitly stated that @assert should
# do so. As such, the rest of the code did not execute.
@timeit @assert factorial(5)<0

同样,这是一个愚蠢的例子,但说明了以上几点并解决了你的问题。