为什么生成器与二维理解中的理解不同

Why is generator not identical to comprehension in 2D comprehension

在以下表达式(版本 0.6.2)中,一个生成器生成一维数组和另一个生成二维数组之间的逻辑是什么:

julia> collect((a,b,c) for (a,b) in ((i,j) for i in 1:2 for j in 3:4), c in 5:6)
8-element Array{Tuple{Int64,Int64,Int64},1}:
 (1, 3, 5)
 (1, 4, 5)
 (2, 3, 5)
 (2, 4, 5)
 (1, 3, 6)
 (1, 4, 6)
 (2, 3, 6)
 (2, 4, 6)

julia> collect((a,b,c) for (a,b) in [(i,j) for i in 1:2 for j in 3:4], c in 5:6)
4×2 Array{Tuple{Int64,Int64,Int64},2}:
 (1, 3, 5)  (1, 3, 6)
 (1, 4, 5)  (1, 4, 6)
 (2, 3, 5)  (2, 3, 6)
 (2, 4, 5)  (2, 4, 6)

唯一的区别是用第二个表达式中的理解替换第一个表达式中的生成器。

((i,j) for i in 1:2 for j in 3:4)[(i,j) for i in 1:2, j in 3:4] 被解析为带有最终 flatten 操作的表达式。表达式 [(i,j) for i in 1:2, j in 3:4] 被收集到一个向量中,赋予它 iteratorsize HasShape 因此它在产品中表现良好。

Base.iteratorsize(f(i,j) for i in 1:2 for j in 3:4)一般是SizeUnknown因为我们不知道f的return类型和产品中的运算符使用 SizeUnknown 使整个产品 SizeUnknown 并因此在收集时变平。

您可能还在寻找

julia> collect((a,b,c) for (a,b) in ((i,j) for i in 1:2, j in 3:4), c in 5:6)
2×2×2 Array{Tuple{Int64,Int64,Int64},3}

julia> collect((a,b,c) for (a,b) in [(i,j) for i in 1:2, j in 3:4], c in 5:6)
2×2×2 Array{Tuple{Int64,Int64,Int64},3}:

(没有扁平化参与形成第一个生成器,一切顺利)。

编辑:我认为现在 Base.iteratorsize(f(i,j) for i in 1:2 for j in 3:4) 可以是 HasShape,我将尝试将该行为添加到 flatten