对外部范围的理解失去输出类型
comprehension over external range loses output type
又是一个新手问题,我觉得这个区别很迷惑:
it = 1:3
typeof([i^2 for i in 1:3]) # Array{Int64,1}
typeof([i^2 for i in it]) # Array{Any,1}
为什么 运行ge 的定义位置很重要?
typeof([i^2 for i in it::UnitRange{Int64}])
似乎给出了提示,this discussion 也是如此。但是,无论上述行为的原因如何,实际问题都是:我如何 specify/enforce 理解的输出类型?
编辑:一个更完整的例子说明了两个不同的问题,
# 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
我首先在函数中遇到了问题,其中使用向量与 运行ge 会产生不同的输出类型,在尝试解决此问题时,我在全局命名空间和 运行 中进行了实验另一个问题...
考虑以下代码
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}
基本上,类型推断在全局范围内要困难得多,而 Julia 主要依靠它。这通常不是问题,因为所有 "real" 代码的范围都很好并且在 REPL 中不是 运行。数组理解 can 有时会有类型推断问题,尽管通常有一些原因(即你 "comprehending" 上面的东西没有具体类型,或者你正在评估的函数内部理解不是类型稳定的)。你总是可以让 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}
但我不希望通常需要它。当然,有些人喜欢对他们的类型非常明确assertions/declarations,所以如果你想确定,你可以使用这个。
又是一个新手问题,我觉得这个区别很迷惑:
it = 1:3
typeof([i^2 for i in 1:3]) # Array{Int64,1}
typeof([i^2 for i in it]) # Array{Any,1}
为什么 运行ge 的定义位置很重要?
typeof([i^2 for i in it::UnitRange{Int64}])
似乎给出了提示,this discussion 也是如此。但是,无论上述行为的原因如何,实际问题都是:我如何 specify/enforce 理解的输出类型?
编辑:一个更完整的例子说明了两个不同的问题,
# 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
我首先在函数中遇到了问题,其中使用向量与 运行ge 会产生不同的输出类型,在尝试解决此问题时,我在全局命名空间和 运行 中进行了实验另一个问题...
考虑以下代码
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}
基本上,类型推断在全局范围内要困难得多,而 Julia 主要依靠它。这通常不是问题,因为所有 "real" 代码的范围都很好并且在 REPL 中不是 运行。数组理解 can 有时会有类型推断问题,尽管通常有一些原因(即你 "comprehending" 上面的东西没有具体类型,或者你正在评估的函数内部理解不是类型稳定的)。你总是可以让 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}
但我不希望通常需要它。当然,有些人喜欢对他们的类型非常明确assertions/declarations,所以如果你想确定,你可以使用这个。