为什么联合类型Array{Union{Missing, Float64},1}
不接受Array{Float64,1}
function somefn(; serie::Vector{Union{Missing, Float64}})
end
serie = [1.0, 2.0, 1.0, 4.0]
somefn(serie = serie)
ERROR: TypeError: in keyword argument serie, expected Array{Union{Missing, Float64},1}, got Array{Float64,1}
Stacktrace:
[1] (::var"#kw##somefn")(::NamedTuple{(:serie,),Tuple{Array{Float64,1}}}, ::typeof(somefn)) at ./none:0
[2] top-level scope at REPL[12]:1
修复它的一种方法是从函数签名中删除Vector{Union{Missing, Float64}}
,我不想这样做,我想明确限制函数参数的可能类型,以减少错误并更容易理解函数的工作原理。
原因在 Julia 手册的参数化复合类型部分中进行了解释。
简而言之,在 Julia 类型中,除了元组是不变的。引用文档:
最后一点非常重要:即使
Float64 <: Real
我们也没有Point{Float64} <: Point{Real}
。
修复代码以使其正常工作的方法是编写:
function somefn(; serie::Vector{<:Union{Missing, Float64}})
end
或
function somefn(; serie::Vector{T}) where {T<:Union{Missing, Float64}}
end
这在手册的该部分稍后将解释。
要理解的关键是Vector{<:Union{Missing, Float64}}
匹配参数为Union{Missing, Float64}
子类型的所有类型,而Vector{Union{Missing, Float64}}
参数必须Union{Missing, Float64}
完全匹配。
因此,在您的原始代码示例中,以下调用:
somefn(serie = Union{Float64,Missing}[1,2,3])
将工作,因为类型参数将匹配。