我想问一下我在 Julia 身上注意到的一些奇怪的行为。考虑以下片段:
function wut()
mat::Array{Number,2}=[1 2 3; 5 6 7]
mat2::Array{Number,2}=[1 1; 2 3]
return typeof(mat2*mat)
end
wut()
非常自豪,这输出 Array{Any,2}
.这里发生了什么?为什么不是输出 Array{Number,2}
?如果换成Number
与 Float64
输出为 Array{Float64,2}
理所当然,但为什么 julia 认为由抽象“数字”组成的两个矩阵的乘法应该作为由“太阳底下的任何事物”组成的矩阵出现?
最佳答案
这是一个替代答案:这是理想情况下不应该存在的怪癖和实现细节。它不是 Julia 的类型设计或调度的结果,也不是真正伟大的设计模式。这只是现状。
矩阵乘法基于就地 API。即,A*B
变成 mul!(output_array, A, B)
.因此,我们需要在真正知道会发生什么之前预先分配结果。这种输出元素类型的计算是由一个古怪且不明确的函数完成的:promote_op
.这是真正应该删除的东西,但需要一个巨大而困难的重构......因此我们有这样的奇怪案例。
更多详细信息,请参见 Base.promote_op
的文档字符串(请注意,它是未导出的,甚至没有出现在在线手册中):
help?> Base.promote_op
promote_op(f, argtypes...)
Guess what an appropriate container eltype would be for storing results of
f(::argtypes...). The guess is in part based on type inference, so can
change any time.
│ Warning
│
│ Due to its fragility, use of promote_op should be avoided. It is
│ preferable to base the container eltype on the type of the actual
│ elements. Only in the absence of any elements (for an empty result
│ container), it may be unavoidable to call promote_op.
有关 promote_op
的更多内部详细信息见问题 #19669 , comments in #25689 , 和 their discussion .
关于types - Julia 矩阵乘法类型行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65906216/