Metadata
Metadata是符号变量中的一种信息载体。其定义于SymbolicUtlis.jl,被纳入Symbolics.jl的符号计算体系中。从而被Modelingtoolkit.jl、Sims.jl等用于构建符号模型系统。
Metadata的类型
为了得知Metadata的源头,首先定义一个符号。
PS:以下代码都在Julia REPL中操作。
julia> using ModelingToolkit
julia> @variables data
1-element Vector{Num}:
data
julia> typeof(data)
Num
可以看到,符号的类型是Num,这一点从vector储存的类型和data的类型都可以证实。
那么Num中有哪些字段?
julia> fieldnames(Num)
(:val,)
julia> data.val
data
可以看到有一个字段(或者说成员):val。调用它之后,还是显示data。这应该不是它的“真面目”。
julia> typeof(data.val)
Sym{Real, Base.ImmutableDict{DataType, Any}}
julia> fieldnames(Sym)
(:name, :metadata)
查看data.val的类型后发现,它是Sym类型。查看Sym的字段,又发现它有两个字段::name和*:metadata*。
julia> data.val.name
:data
julia> data.val.metadata
Base.ImmutableDict{DataType, Any} with 1 entry:
VariableSource => (:variables, :data)
分别查看两个字段中的内容。可以发现,name中存储的是符号名,metadata是可变字典类型,字典的key是DataType类型,value是Any类型。
操作Metadata
从SymbolicUtils.jl的源码中可以看到Metadata的处理函数有 setmetadata,hasmetadata, getmetadata。
setmetadata
使用setmetadata操作“打标签”。
使用方法为:
julia>?setmetadata
setmetadata(s::SymbolicUtils.Symbolic, ctx::DataType, val)
简单来说就是,给符号s,以ctx的类型为标签,给一个值val
julia> struct mystruct end
julia> data = setmetadata(data,mystruct,1.0)
data
julia> data.val.metadata
Base.ImmutableDict{DataType, Any} with 2 entries:
mystruct => 1.0
VariableSource => (:variables, :data)
可以看到,metadata里多了一项!
julia> data = setmetadata(data,mystruct,"test")
data
julia> data.val.metadata
Base.ImmutableDict{DataType, Any} with 2 entries:
mystruct => "test"
VariableSource => (:variables, :data)
可以看到,1.0被修改成了"test"。
PS:ImmutableDict类型的特点是只能被覆盖修改,不能被删除。
再来一个标签!
julia> struct mysecondstruct end
julia> data = setmetadata(data,mysecondstruct,:ok)
data
julia> data.val.metadata
Base.ImmutableDict{DataType, Any} with 3 entries:
mysecondstruct => :ok
mystruct => "test"
VariableSource => (:variables, :data)
嗯哼,又多了一个!再来一个非空标签。
julia> struct mythirdstruct
mynum::Int64
end
julia> data = setmetadata(data,mythirdstruct,1)
data
julia> data.val.metadata
Base.ImmutableDict{DataType, Any} with 4 entries:
mythirdstruct => 1
mysecondstruct => :ok
mystruct => "test"
VariableSource => (:variables, :data)
可以看到,标签的val和struct本身没有关系!
hasmetadata
julia>?hasmetadata
hasmetadata(s::SymbolicUtils.Symbolic, ctx)
查看ctx是不是s的metadata的key。
julia> hasmetadata(data,mystruct)
true
julia> hasmetadata(data,mysecondstruct)
true
julia> hasmetadata(data,mythirdstruct)
true
julia> hasmetadata(data,Int64)
false
getmetadata
getmetadata(s::SymbolicUtils.Symbolic, ctx)
获得metadata中key为ctx的值。
julia> getmetadata(data,mystruct)
"test"
julia> getmetadata(data,mysecondstruct)
:ok
julia> getmetadata(data,mythirdstruct)
1
Metadata存在的意义
目前还没有探究清楚,根据符号的特点猜测,应该是在构建符号计算体系时需要。