Julia允许使用理解语法轻松构造数组:
null
我假设对于类型稳定表达式,编译器首先确定泛型元素的类型,可迭代的长度,然后预先分配和初始化数组及其内容。
但是,有时候,首选嵌套for循环。这可能是因为数组有很多维度,或者因为第二个可迭代的长度取决于第一个,或者因为表达式很复杂并且计算它有副作用。
在这种情况下,上述代码可以扩展为
A = [ sqrt(i)^2+j for i in 0:10, j in 1:3 ]
如何以简单,易读,易于维护的方式计算T = ???
A = Array{T}(11,3)
for i in 0:10
for j in 1:3
A[i,j] = sqrt(i)^2 + j
end
end
?有没有办法手动调用列表推导引擎下使用的类型推断机制?我认为不满意的解决方案是:
T
c ++ T = Float64 # Not my job to do the compiler's work...
T = typeof(sqrt(0)^2+1) # Or is the argument of typeof not evaluated in this case?
机制的某些方面可能是什么?
答案 0 :(得分:3)
实际上,并非那么简单。用于使用类型推断选择元素类型的理解,但据我所知,已经远离了它。
现在(我相信),初始元素类型被视为第一个元素的类型。需要时,扩展元素类型并重新分配数组。如果结果元素类型是可以通过类型推断推断的具体类型,则结果代码仍然像元素类型直接基于类型推断一样高效。
理解已经远离直接依赖于类型推断的原因在于它是一种优化,使Julia代码运行得更快,而不是Julia语义的一部分。在实践中,julia并不总是能够推断出紧密类型,并且推理结果可能因julia版本而异,因此不希望使代码行为依赖于它(当然,性能会有所不同)。
考虑到您的原始问题:如果您让用户在这种情况下提供结果类型T
,我经常会发现它可以减少令人惊讶的代码。我所描述的用于理解的机制也被map
使用(或多或少被broadcast
使用,但到目前为止它们并不完全一致),但它没有直接暴露给用户(不知道这样做是否有意义。)
答案 1 :(得分:1)
有未记录的无证件Base.return_types
。它在测试中被大量使用,因此在tests目录中搜索以查找用法。请注意Toivio的答案,并做好准备,推断可能会放弃,只需在新版本的Julia中返回Any
相同的表达式。