2017-02-14 122 views
5

我需要获取某个类型的无参数版本。例如,可以说我有x = [0.1,0.2,0.3]。然后typeof(x)==Array{Float64,1}。我如何制作一个功能(或者是否存在?)parameterless_type(x) == Array?我需要以通用的形式得到它,以访问没有其中的类型参数的构造函数。获取无参数类型

+1

'typeof(x).name'给了我'Array'。它可能会诀窍,但不会被官方认可的朱莉娅。 –

+2

ColorTypes.jl做到这一点和许多相关的技巧,可能是一个有用的模型? – tholy

回答

2

这似乎在0.5

julia> typeof(a) 
Array{Float64,1} 

julia> (typeof(a).name.primary)([1 2 3]) 
1×3 Array{Int64,2}: 
1 2 3 

编辑工作1:

由于勒托利的评论和ColorTypes.jl包,0.6的解决方案是:

julia> (typeof(a).name.wrapper)([1 2 3]) 
1×3 Array{Int64,2}: 
1 2 3 

编辑2:

凤阳王说服了我,使用typename是必要的。特别是,Array{Int}.name因0.6失败,因为Array{Int}现在是UnionAll。一个定义在0.5和0.6的工作是

using Compat.TypeUtils: typename 

if :wrapper in fieldnames(TypeName) 
    parameterless_type(T::Type) = typename(T).wrapper 
else 
    parameterless_type(T::Type) = typename(T).primary 
end 

parameterless_type(x) = parameterless_type(typeof(x)) 

就这样,它是

parameterless_type([0.1,0.2,0.3]) == Array 
parameterless_type(Array{Int}) == Array 
+1

这在0.6上失败。最好使用库函数而不是字段访问。 –

+0

@FenggyangWang这个用例没有库函数。因此,我认为使用上述方法没有问题。当然,我会将这些代码包装在我自己的函数中('ColorTypes.jl'称为'basetype'),以便在更新中断时很容易修复。 – tim

+0

对于至少'.name'字段访问,应该使用库函数'typename'。如果你在'VecOrMat {Int}'上试试这个,就可以看到'.name'。 –

4

的正确方法,既0.5和0.6兼容,是使用Compat

julia> using Compat 

julia> Compat.TypeUtils.typename(Array{Int, 2}) 
Array 

julia> Compat.TypeUtils.typename(Union{Int, Float64}) 
ERROR: typename does not apply to unions whose components have different typenames 
Stacktrace: 
[1] typename(::Union) at ./essentials.jl:119 

julia> Compat.TypeUtils.typename(Union{Vector, Matrix}) 
Array 
+0

这将返回一个'TypeName'。有没有一种方法(除了'eval')在0.6上调用适当的构造函数? – tim

+2

@Tim适当的类型可以使用'.wrapper'从'TypeName'中恢复;尽管这种直接现场访问在未来很容易破裂。 –