反射和內省

Julia 提供各種執行時期反射功能。

模組繫結

Module 的匯出名稱可使用 names(m::Module) 取得,它會傳回一個 Symbol 元素陣列,代表匯出的繫結。names(m::Module, all = true) 傳回 m 中所有繫結的符號,不論匯出狀態為何。

DataType 欄位

DataType 欄位的名稱可以使用 fieldnames 查詢。例如,給定下列類型,fieldnames(Point) 會傳回一個 Symbol 元組,代表欄位名稱

julia> struct Point
           x::Int
           y
       end

julia> fieldnames(Point)
(:x, :y)

Point 物件中每個欄位的類型儲存在 Point 變數本身的 types 欄位中

julia> Point.types
svec(Int64, Any)

雖然 x 標註為 Int,但 y 在類型定義中未標註,因此 y 預設為 Any 類型。

類型本身表示為稱為 DataType 的結構

julia> typeof(Point)
DataType

請注意,fieldnames(DataType) 提供 DataType 本身的每個欄位的名稱,而其中一個欄位是上述範例中觀察到的 types 欄位。

子類型

任何 DataType直接子類型都可以使用 subtypes 列出。例如,抽象 DataType AbstractFloat 有四個(具體)子類型

julia> subtypes(AbstractFloat)
4-element Vector{Any}:
 BigFloat
 Float16
 Float32
 Float64

任何抽象子類型也會包含在此清單中,但其進一步的子類型不會;可以遞迴應用 subtypes 來檢查完整的類型樹。

DataType 佈局

與 C 程式碼介接時,DataType 的內部表示非常重要,而且有幾個函式可用於檢查這些詳細資料。如果 T 以相容於 C 的對齊方式儲存,則 isbitstype(T::DataType) 會傳回 true。 fieldoffset(T::DataType, i::Integer) 會傳回欄位 i 相對於類型開頭的(位元組)偏移量。

函式方法

任何一般函式的函式可以使用 methods 列出。可以使用 methodswith 搜尋方法傳送表格,以接受指定的類型。

擴充與縮減

如在元程式設計章節中所討論的,macroexpand函式提供給定巨集的未引用且內插的表達式(Expr)形式。若要使用macroexpand,請引用表達式區塊本身(否則,巨集會被評估,而結果會被傳遞!)。例如

julia> macroexpand(@__MODULE__, :(@edit println("")) )
:(InteractiveUtils.edit(println, (Base.typesof)("")))

函式Base.Meta.show_sexprdump用於顯示任何表達式的S-expr樣式檢視和深度巢狀詳細檢視。

最後,Meta.lower函式提供任何表達式的lowered形式,對於了解語言結構如何映射到原始操作(例如賦值、分支和呼叫)特別感興趣

julia> Meta.lower(@__MODULE__, :( [1+2, sin(0.5)] ))
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope`
1 ─ %1 = 1 + 2
│   %2 = sin(0.5)
│   %3 = Base.vect(%1, %2)
└──      return %3
))))

中間和編譯表示式

檢查函式的縮減形式需要選擇要顯示的特定方法,因為泛型函式可能有多個具有不同類型簽章的方法。為此,可以使用code_lowered進行特定於方法的程式碼縮減,並且可以使用code_typed進行類型推論形式。 code_warntype會將重點標示新增到code_typed的輸出中。

更接近機器,可以使用code_llvm列印函式的LLVM中間表示式,最後可以使用code_native取得編譯的機器碼(這將觸發任何先前尚未呼叫的函式的JIT編譯/程式碼產生)。

為了方便起見,上述函式有巨集版本,它們採用標準函式呼叫並自動擴充引數類型

julia> @code_llvm +(1,1)
;  @ int.jl:87 within `+`
; Function Attrs: sspstrong uwtable
define i64 @"julia_+_476"(i64 signext %0, i64 signext %1) #0 {
top:
  %2 = add i64 %1, %0
  ret i64 %2
}

如需更多資訊,請參閱 @code_lowered@code_typed@code_warntype@code_llvm@code_native

除錯資訊列印

上述函式和巨集會接受關鍵字引數 debuginfo,用來控制列印的除錯資訊層級。

julia> @code_typed debuginfo=:source +(1,1)
CodeInfo(
    @ int.jl:53 within `+'
1 ─ %1 = Base.add_int(x, y)::Int64
└──      return %1
) => Int64

debuginfo 的可能值為::none:source:default。預設不列印除錯資訊,但可以透過設定 Base.IRShow.default_debuginfo[] = :source 來變更。