分析与反省
数据类型字段
julia> struct Point
x::Int
y
end
julia> fieldnames(Point)
(:x, :y)
每个字段的类型 点 对象存储在 类别 领域的 点 变量本身:
julia> Point.types
svec(Int64, Any)
虽然变量 x 被标记为 Int型,注释从 y 在类型定义中,所以 y 有类型 任何 默认情况下。
类型本身表示为 数据类型 结构:
julia> typeof(Point)
DataType
请注意, 字段名(数据类型) 函数返回每个字段的名称 数据类型 结构本身,其中一个领域是 类别 字段如上例所示。
数据类型结构
的内部表示 数据类型’在与C代码交互时非常重要。 有几个函数可用于分析。 `isbitstype(T::数据类型)如果类型返回true T 以与C兼容的对齐方式存储。 fieldoffset(T::DataType,i::Integer)返回_i_字段相对于类型开头的偏移量(以字节为单位)。
扩张和降级
章中所述 元编程,函数 'macroexpand`返回表达式的插值形式(Expr)没有这个宏的引号。 要使用 macroexpand',将表达式块本身用引号括起来(`报价)(否则,将评估宏本身并传输其结果)。 例子::
julia> macroexpand(@__MODULE__, :(@edit println("")) )
:(InteractiveUtils.edit(println, (Base.typesof)("")))
功能 基地。元。显示_sexpr 和 垃圾场用于以符号形式表示表达式,并显示任何表达式的深度嵌入内容的信息。
最后,功能 元。较低返回 降低了 任何表达式的形式,对于理解语言结构如何映射到原始操作(如赋值、分支和调用)特别有用。:
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_warntype为输出数据添加高亮显示 代码类型.
在更接近机器级别的级别上,可以使用以下方法导出LLVM函数的中间表示 code_llvm',并且编译后的机器代码可通过 `编码,编码(这会为之前未被调用的任何函数启动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,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,debuginfo 是: :无', `:资料来源,并 :默认'。 默认情况下,不显示调试信息。 要更改此行为,请设置 `基地。IRShow。default_debuginfo[]=:来源.