Union of Integer,AbstractVector {Integer}和String

时间:2015-08-08 11:12:31

标签: 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

我希望有一种方法让用户指定应该处理所有列,最后我更改了函数,以便这是默认行为:

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)

为什么整数,整数向量和字符串之间的这种联合似乎不起作用?

2 个答案:

答案 0 :(得分:1)

问题是Julia在传递字符串时无法推断出类型T,因此无法解析调用哪种方法。

考虑以下两个函数fg

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与上面的fg进行比较:

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