2015-03-02 26 views
4

另一個新手的問​​題,我覺得這個區別很迷惑:理解在外部範圍的丟失輸出型

it = 1:3 
typeof([i^2 for i in 1:3]) # Array{Int64,1} 
typeof([i^2 for i in it]) # Array{Any,1} 

爲什麼它身在何處的範圍被定義?

typeof([i^2 for i in it::UnitRange{Int64}])似乎給出了一個提示,因爲this discussion。然而,不管上述行爲的原因,實際問題將是:我如何指定/強制理解的輸出類型?

編輯:更全面的例子示出了兩個不同的問題,

# global namespace 

nu1 = 0.5 + [0 ,1:3] 
nu2 = 0.5 + (0:3) 
typeof([besselj(_nu,[1,2]) for _nu in nu1]) # Any 
typeof([besselj(_nu,[1,2]) for _nu in nu2]) # Any 
typeof([besselj(_nu,[1,2]) for _nu in 0.5 + (0:3)]) # correct inference 

# within a function 

function rb() 
    nu = 0.5 + [0 ,1:3] 
    bj = [besselj(_nu,[1,2]) for _nu in nu] 
end 

function rb2() 
    nu = 0.5 + (0:3) 
    bj = [besselj(_nu,[1,2]) for _nu in nu] 
end 

typeof(rb()) # Any 
typeof(rb2())# Correct inference 

我先打一個函數,其中使用矢量Vs的範圍產生不同的輸出類型,內的問題,並在試圖解決這個我嘗試全局命名空間,衝進其他問題...

回答

4

考慮下面的代碼

it = 1:3 
@show typeof([i^2 for i in 1:3]) 
@show typeof([i^2 for i in it]) 

function foo() 
    it = 1:3 
    @show typeof([i^2 for i in 1:3]) 
    @show typeof([i^2 for i in it]) 
end 

foo() 

產生

typeof($(Expr(:comprehension, :(i^2), :(i = 1:3)))) => Array{Int64,1} 
typeof($(Expr(:comprehension, :(i^2), :(i = it)))) => Array{Any,1} 
typeof($(Expr(:comprehension, :(i^2), :(i = 1:3)))) => Array{Int64,1} 
typeof($(Expr(:comprehension, :(i^2), :(i = it)))) => Array{Int64,1} 

在全球範圍內,基本類型推理困難得多,而朱莉婭大部分都是對它進行分類。這通常不是一個問題,因爲所有「真實」代碼的範圍很廣,並且不在REPL上運行。數組理解可能有時會出現類型推理問題,雖然通常有某些原因(即,您「理解」的內容不是具體的類型,或者您在理解內部評估的函數不是類型穩定的)。您可以隨時讓朱莉婭知道輸出應該是使用通常的語法鍵入的載體是什麼類型,即

it = 1:3 
x = [i^2 for i in 1:3] 
@show typeof(x) # typeof(x) => Array{Int64,1} 
y = Int[i^2 for i in it] 
@show typeof(y) # typeof(y) => Array{Int64,1} 

,但我不希望給需要這個正常。當然,有些人喜歡對他們的類型斷言/聲明非常明確,所以如果你想確定你可以使用它。

+0

有趣的,因爲我有一個功能內的問題:S – baptiste 2015-03-02 23:19:11

+0

我已經添加了一些東西來解決這兩點。你有具有類型推斷問題的實際代碼嗎? – IainDunning 2015-03-02 23:21:28

+0

非常好,謝謝。我試圖把它縮小到一個最小的例子。 – baptiste 2015-03-02 23:24:23