我有一个函数,用户在其中传递一个参数来选择矩阵的哪些列应该被处理,如下面的简约示例所示:
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
我希望有一种方法让用户指定应该处理所有列,最后我更改了函数,以便这是默认行为:
function foo{P<:Real, T<:Integer}(;x::AbstractMatrix{P}=zeros(3, 10), colN::Union(T, AbstractVector{T})=[1:size(x)[2]])
x[:,colN] = x[:,colN]+1
return x
end
最初,我想允许colN
参数取String
,这样用户就可以传递值&#34; all&#34;意味着应该处理所有列,但以下内容并不像我预期的那样工作:
function foo{P<:Real, T<:Integer}(;x::AbstractMatrix{P}=zeros(3, 10), colN::Union(T, AbstractVector{T}, String)="all")
if colN == "all"
colN = [1:size(x)[2]]
end
x[:,colN] = x[:,colN]+1
return x
end
调用该函数的最后一个版本给出:
foo(colN="all")
ERROR: `__foo#8__` has no method matching __foo#8__(::Array{Float64,2}, ::ASCIIString)
为什么整数,整数向量和字符串之间的这种联合似乎不起作用?
答案 0 :(得分:1)
问题是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
在这种情况下,您将观察到以下行为:
f(1)
为1
,因为T
的价值可以推断f("hello")
发出错误,因为T
的值未知g(1, "hello")
为"hello"
,因为T
的价值可以推断话虽如此,我认为使用multiple dispatch代替Union
类型来实现您想要做的事情会更加惯用朱莉娅。
更新。看到您的colN
是字符串或索引列表,我相信您可以使用T = Int
(或Int64
你想要解决很多内存)。将以下函数h
与上面的f
和g
进行比较:
function h(x::Union(Int,String))
x
end
在这种情况下,h(1)
和h("hello")
都按预期工作(例如h(1.0)
会引发错误)。
答案 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(zeros(10,3))
会给你:
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
和foo(zeros(3,10),5)
会给你:
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