Julia 整数、抽象向量{Integer}和字符串的并集
我有一个函数,在该函数中,用户传递一个参数,以选择应处理矩阵的哪些列,如下面的最小示例所示:Julia 整数、抽象向量{Integer}和字符串的并集,julia,Julia,我有一个函数,在该函数中,用户传递一个参数,以选择应处理矩阵的哪些列,如下面的最小示例所示: function foo{P<:Real, T<:Integer}(;x::AbstractMatrix{P}=zeros(3, 10), colN::Union(T, AbstractVector{T})=1) x[:,colN] = x[:,colN]+1 return x end 调用此函数的最后一个版本将提供: foo(colN="all") ERROR: `_
function foo{P<:Real, T<:Integer}(;x::AbstractMatrix{P}=zeros(3, 10), colN::Union(T, AbstractVector{T})=1)
x[:,colN] = x[:,colN]+1
return x
end
调用此函数的最后一个版本将提供:
foo(colN="all")
ERROR: `__foo#8__` has no method matching __foo#8__(::Array{Float64,2}, ::ASCIIString)
为什么整数、整数向量和字符串之间的这种并集似乎不起作用?问题在于,当传递字符串时,Julia无法推断类型
t
,因此无法确定要调用哪个方法
考虑以下两个函数,f
和g
:
function f{T<:Integer}(x::Union(T,String))
x
end
function g{T<:Integer}(y::T, x::Union(T,String))
x
end
在这种情况下,
h(1)
和h(“hello”)
都按预期工作(例如,h(1.0)
会引发错误) 无需在此函数中传递字符串来指示处理所有列。
另外,看起来矩阵应该作为位置参数传入,
而不是关键字参数。
这样茱莉亚就可以专攻它了。
朱莉娅有很多方法可以更有效地处理这个问题
function foo{P<:Real, T<:Integer}(x::AbstractMatrix{P}, colN::Union(T, AbstractVector{T}))
x[:,colN] += 1
return x
end
function foo{P<:Real}(x::AbstractMatrix{P})
x[:,[1:size(x)[2]]] += 1
return x
end
和foo(零(3,10,5)
将为您提供:
3x10 Array{Float64,2}:
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
3x10 Array{Float64,2}:
0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
谢谢你的回答。我同意使用多个分派的建议,但就我所知,参数
colN
不能是关键字参数,我更喜欢这样,因为我要编写的实际函数有大量参数。如果您必须使用名称colN
作为字符串,一个整数或一个整数数组,不指定T
和colN
的类型如何?是的,这是一个选项,但我应该确保在函数内部,用户不会传递除整数、整数向量或字符串以外的内容作为colN
值,如果他/她没有说明如何使用Int64
而不是T
(如果要使用平台本机整数,只需Int
),则抛出一条有用的错误消息?这样,您就可以坚持使用Union
,并最终简化您的函数。关于更新,h(x::Union(Int,String))
不适用于整数数组,只适用于单个索引。谢谢回答。正如我刚才在对@vindvaki答案的评论中所说的,我更喜欢colN
作为关键字参数。我在问题中展示的示例函数是最简单的,实际函数有许多参数,因此我更喜欢使用关键字参数。好的,但您仍然可以简单地使用没有colN关键字参数表示“全部”,将其默认为nothing
,而不必比较字符串,或者默认为0
,并将0
视为表示“全部”的特殊值。最后一种解决方案是可行的,但我希望函数调用能够方便且立即被用户读取,因此我更喜欢类似“全部”的内容,而不是类似“0”的任意内容来表示处理所有列。当然,这是主观偏好的问题。关于另一种解决方案,请给出一个工作示例?如果我尝试将colN
更改为默认值nothing
colN::Union(T,AbstractVector{T})=nothing
,然后在不传递参数的情况下调用该函数,我会得到错误:
\uuufoo#1\ufoo#没有匹配的方法(::Array{Float64,2},::nothing)`。
function foo{P<:Real, T<:Integer}(x::AbstractMatrix{P}, colN::Union(T, AbstractVector{T}))
x[:,colN] += 1
return x
end
function foo{P<:Real}(x::AbstractMatrix{P})
x[:,[1:size(x)[2]]] += 1
return x
end
3x10 Array{Float64,2}:
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0
3x10 Array{Float64,2}:
0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 0.0 0.0