2015-03-02 1 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. Однако, независимо от причины описанного выше поведения, практический вопрос будет следующим: как указать/ввести в действие тип вывода понимания?

Edit: Более подробный пример иллюстрирует два отдельных вопрос,

# 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 

Я первый ударил вопрос в функции, где с использованием вектора против диапазона производит различные типы продукции, и при попытке решить эту проблему, я экспериментировал в глобальном пространстве имен и побежал в другой вопрос ...

ответ

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. Массивные осмысления могут иногда имеют проблемы с типом вывода, хотя обычно существует некоторая причина (т. Е. Вещь, которую вы «понимаете», не набирается конкретно, или функция, которую вы оцениваете внутри понимания, не устойчива к типу). Вы всегда можете позволить Julia знать, какой тип вывода должен использовать обычный синтаксис для типизированного вектора, т.е.

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

+0

Я добавил что-то, чтобы адресовать обе эти точки. У вас есть фактический код с проблемой вывода типа? – IainDunning

+0

Отлично, спасибо. Я пытаюсь сузить его до минимального примера. – baptiste