尽管(以某种方式)定义了MethodError

时间:2017-11-24 01:27:29

标签: julia

我正在尝试做这样的事情:

function outer(x::Array{Float64}, y::Array{Float64}=nothing)
    if (y == nothing)
        function inner(y::Array{Float64})
            return x .* y
        end
        return inner
    else
        return x .+ y
    end
end

outer([2.], [3.])  # to return 5, works
outer([2.])([3.])  # to return 6, fails.

outer([2.], [3.])效果很好。

问题outer([2.])([3.])提出MethodError说明:

MethodError: no method matching outer(::Array{Float64,1}, ::Void)
Closest candidates are:
  outer(::Array{Float64,N} where N) at In[1]:2
  outer(::Array{Float64,N} where N, ::Array{Float64,N} where N) at In[1]:2

Stacktrace:
 [1] outer(::Array{Float64,1}) at ./In[1]:2
 [2] include_string(::String, ::String) at ./loading.jl:522

奇怪的是,在Closest candidates下,单参数outer(::Array{Float64,N} where N)是第一个候选者。那么为什么它不适用于单个论点呢?

注意:outer([2.], )([3.])outer([2.], nothing)([3.])outer([2.], [nothing])([3.])都会产生相同(相似)的错误。

这也可以使用单个参数函数重现:

function outer(y::Array{Float64}=nothing)
    if (y == nothing)
        function inner(y::Array{Float64})
            return y .* y
        end
        return inner
    else
        return y .+ y
    end
end

outer([2.])
1-element Array{Float64,1}:
 4.0

outer()([3.])
MethodError: no method matching outer(::Void)
Closest candidates are:
  outer() at In[6]:2
  outer(::Array{Float64,N} where N) at In[6]:2
  outer(::Array{Float64,N} where N, ::Array{Float64,N} where N) at In[1]:2

Stacktrace:
 [1] outer() at ./In[6]:2
 [2] include_string(::String, ::String) at ./loading.jl:522

同样,outer()列表中首先列出了零参数函数Closest candidates

基本上,上面的示例是表示对数和/似然评估的MWE,其中xdatay是模型的parameter。我试图在模型的参数中返回一个函数以使用MLE进行优化,或者在参数传递时返回log-sum。

在这个类比中,outer计算log-sum,给定数据和参数,或者返回inner作为参数的函数,可以对其进行优化。

2 个答案:

答案 0 :(得分:3)

您可以简单地重现这一点:

f(x::Float64=nothing) = x
f()

添加= nothing时,不设置任何默认参数。并且还添加了f()作为方法。但是当您致电f()时,julia会尝试运行f(nothing),因为nothing是您的默认参数。那将是错误,因为nothing的类型为Void您断言参数必须为 Float64

例如,你可以(但不应该)使用f(x::Union{Float64,Void}=nothing) = x来解决这个问题。但是使用Nullable会更好,这恰好是与可能存在或不存在的值进行交互。

了解有关Nullables here的更多信息或在REPL中输入?Nullable

按OP

编辑

MWE:

function outer(x::Array{Float64}, y=Nullable{Array{Float64}}())
    if isnull(y)
        function inner(y::Array{Float64})
            return x .* y
        end
        return inner
    else
        return x .+ y
    end
end

outer([2.])([3.])  # Produces 6,
outer([2.], [3.])  # Produces 5.

按预期工作。

答案 1 :(得分:1)

可读性计算所以也许您必须重新考虑明确定义2个方法(并且简单,因为它采用Julian方式):

outer(x::Array{Float64}, y::Array{Float64}) = x .+ y
outer(x::Array{Float64}) = y -> x .* y