问题描述
是否有一种方法可以迭代Tuple{...}
数据类型中包含的类型?例如,如果我的类型为Tuple{String,Int}
,我希望能够使用类似values(Tuple{String,Int})
的东西来返回String
和Int
的迭代器,如下所示:
julia> collect(values(Tuple{String,Int}))
2-element Array{DataType,1}:
String
Int64
但是,那当然是行不通的:
julia> values(Tuple{String,Int})
Tuple{String,Int64}
julia> collect(values(Tuple{String,Int}))
ERROR: MethodError: no method matching length(::Type{Tuple{String,Int64}})
Closest candidates are:
length(::Core.SimpleVector) at essentials.jl:596
length(::Base.MethodList) at reflection.jl:852
length(::Core.MethodTable) at reflection.jl:938
...
Stacktrace:
[1] _similar_for(::UnitRange{Int64},::Type{Any},::Type{T} where T,::Base.HasLength) at ./array.jl:576
[2] _collect(::UnitRange{Int64},::Base.HasEltype,::Base.HasLength) at ./array.jl:609
[3] collect(::Type{T} where T) at ./array.jl:603
[4] top-level scope at REPL[30]:1
我更喜欢不涉及DataType
内部的解决方案。
解决方法
元组类型仅为DataType
。在其上进行的所有操作都必须涉及DataTypes
-您正在寻找类型为DataType -> [DataType]
的函数。一个可能的答案是Tuple{String,Int}.parameters
。至少在1.3中,Core.Compiler
还包含
datatype_fieldtypes(x::DataType) = ccall(:jl_get_fieldtypes,Any,(Any,),x)
,但仅内部且未记录。两者都产生Core.SimpleVector
。
但是后来我想起了可以将元组部分既视为索引又视为字段的方法。事实证明,fieldtypes
可能是您的最爱:
julia> fieldtypes(Tuple{Int,String})
(Int64,String)
但是,其他方法的优点是可以将它们与 any 参数化类型一起使用。这通常在生成的函数中很方便。