2014-12-23 10 views
7

Quando provo a creare un Array con una lista di comprensione, si traduce in un Array{Any, 1} anche se mi codificare tutti gli elementi a "simbolo":Perché la comprensione di questo elenco restituisce una matrice {Any, 1} invece di una matrice {Symbol, 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 

Perché quella ultima di lista restituire un Array{Any, 1} invece di un Array{Symbol, 1}? Nota che il seguente fa restituire un 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 

È interessante notare che, così fa il seguente:

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  

Che cosa mi manca?

risposta

8

Secondo il numero this discussion nel tracker di emissione del JuliaLang/julia repo on GitHub, il problema sembra derivare da una mancanza del sistema di inferenza del tipo di Julia. Jeff Bezanson (uno degli scrittori Julia e manutentori) ha lasciato un relevant comment in another discussion:

Questo comportamento è in realtà previsto al momento. Poiché [col_names] è globale, potrebbe cambiare ovunque, quindi non possiamo supporre di conoscere il suo tipo. Questo è eccessivamente pessimista, ma è difficile trovare una regola che ci permetta di fare meglio.

Sorprendentemente, forse (as observed by John Myles White), il tipo viene correttamente dedotto se tali operazioni sono effettuate all'interno di una funzione:

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 

Come alternativa alla lista la vostra comprensione, è possibile utilizzare map(symbol, <Array{T,1}>), che fa restituire un Array{Symbol,1}, anche a scope globale:

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 
+1

il principio generale è che le funzioni interne, il comp iler conosce "tutto": i tipi di input e le trasformazioni che verranno applicate. Di conseguenza, può specializzarsi in modo più aggressivo. – tholy

+0

@tholy Grazie per il tuo commento. Riesci a pensare a qualche lettura raccomandata a riguardo? – Jubobs