为什么这个列表理解返回一个数组{Any,1}而不是一个数组{Symbol,1}?

时间:2014-12-23 22:54:33

标签: arrays type-inference julia

当我尝试使用列表推导创建Array时,即使我将所有元素编码为“符号”,也会生成Array{Any, 1}

julia> u_col_names=[symbol("user_id"), symbol("age"), symbol("sex"), symbol("occupation"), symbol("zip_code")]
5-element Array{Symbol,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code 

julia> col_names=["user_id", "age", "sex", "occupation", "zip_code"]
5-element Array{ASCIIString,1}:
 "user_id"   
 "age"       
 "sex"       
 "occupation"
 "zip_code"  

julia> u_col_names=[symbol(col_names[i]) for i in 1:size(col_names)[1]]
5-element Array{Any,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code 

为什么最后一次列表理解会返回Array{Any, 1}而不是Array{Symbol, 1}? 请注意,以下 会返回Array{Symbol, 1}

julia> u_col_names=[symbol("col_names$i") for i in 1:size(col_names)[1]]
5-element Array{Symbol,1}:
 :col_names1
 :col_names2
 :col_names3
 :col_names4
 :col_names5

有趣的是,以下内容也是如此:

julia> col_names[1]
"user_id"

julia> symbol(col_names[1])
:user_id

julia> [symbol(col_names[1]), symbol(col_names[2])]
2-element Array{Symbol,1}:
 :user_id
 :age    

我错过了什么?

1 个答案:

答案 0 :(得分:8)

根据this discussion问题跟踪器中的JuliaLang/julia repo on GitHub,问题似乎源于Julia的类型推理系统的缺陷。 Jeff Bezanson(朱莉娅作家和维护者之一)在relevant comment留下了another discussion

  

目前实际上预计会出现此行为。由于[col_names]是全局的,它可能会在任何地方发生变化,因此我们无法假设我们知道它的类型。这是过于悲观,但很难提出一条让我们做得更好的规则。

令人惊讶的是,或许(as observed by John Myles White),如果这些操作是在函数内部执行的,则正确推断出类型:

julia> function fun()
         col_names=["user_id", "age", "sex", "occupation", "zip_code"]
         return u_col_names=[symbol(item) for item in col_names]
       end
fun (generic function with 1 method)

julia> fun()
5-element Array{Symbol,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code

作为列表理解的替代方法,您可以使用map(symbol, <Array{T,1}>) 返回Array{Symbol,1},即使在全局范围内也是如此:

julia> col_names=["user_id", "age", "sex", "occupation", "zip_code"]
5-element Array{ASCIIString,1}:
 "user_id"   
 "age"       
 "sex"       
 "occupation"
 "zip_code"  

julia> map(symbol, col_names)
5-element Array{Symbol,1}:
 :user_id   
 :age       
 :sex       
 :occupation
 :zip_code