julia學習筆記:元編程-宏(macro)

宏像是一個函數,這個函數接受一組參數返回一個表達式。
一個簡單的宏定義:數組

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

這個宏接收一個參數並返回一個表達式打印一句話,調用:函數

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

一、宏調用spa


兩種調用方式code

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

注意第二種與下面帶空格的調用的區別,下面的調用表示傳一個參數,這個參數是一個元組;而上面第二種調用表示傳遞多個參數以逗號分隔:blog

@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__提供的宏調用的位置信息,用於排查錯誤;如圖:圖片描述string

二、構造高級宏it


下面定義一個簡單的宏@assert,這個宏用來判斷傳入表達式的值,若是是true返回nothing,不然報錯。
Note:報錯信息是將傳入的表達式轉換成字符串,這個沒法用函數實現。io

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)
相關文章
相關標籤/搜索