Julia MethodError,尽管已(以某种方式)定义

Julia MethodError,尽管已(以某种方式)定义,julia,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.],

我正在尝试这样做:

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
奇怪的是,在
最接近的候选项下,单个参数
外部(::数组{Float64,N},其中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()



基本上,上述示例是表示对数和/似然评估的MWE,其中
x
数据
y
是模型的
参数
。我试图在模型的参数中返回一个函数,以使用MLE进行优化,或者如果参数被传递,则返回对数和


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

您可以简单地用以下方法重现:

f(x::Float64=nothing) = x
f()
添加
=nothing
时,将nothing设置为默认参数。并且还添加了
f()
作为方法。但是当您调用
f()
时,julia将尝试运行
f(nothing)
,因为
nothing
是您的默认参数。然后会出现错误,因为
nothing
属于
Void
类型,并且您断言参数必须是
Float64

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

阅读有关Nullable的更多信息,或在REPL中键入
?Nullable


按OP编辑 MWE:
按预期工作。

您只需使用以下方法即可复制:

f(x::Float64=nothing) = x
f()
添加
=nothing
时,将nothing设置为默认参数。并且还添加了
f()
作为方法。但是当您调用
f()
时,julia将尝试运行
f(nothing)
,因为
nothing
是您的默认参数。然后会出现错误,因为
nothing
属于
Void
类型,并且您断言参数必须是
Float64

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

阅读有关Nullable的更多信息,或在REPL中键入
?Nullable


按OP编辑 MWE:
正如预期的那样工作。

可读性很重要,因此您可能需要重新考虑明确定义2种方法(并且以朱利安的方式很简单):


可读性很重要因此,您可能需要重新考虑明确定义2个方法(并且以朱利安的方式很简单):


我查看了
Nullable
类型。但是,我无法让它在函数中工作。你能用
Nullable
类型发布一个MWE来完成你对问题的回答吗(这样我就可以接受你的答案,如果你能让它工作的话)?事实上,我刚刚想出了如何让
Nullable
工作的方法。我在尝试
y::Nullable{Array{Float64}}}=nothing
(这导致了相同的错误),
y::Nullable{Array{Float64}}()
(这会引发
参数错误
),以及
y::Nullable{Array{Float64}}
。解决方案是
y=Nullable{Array{Float64}}()
,因为当我刚才重新阅读文档时,我意识到
Nullable{Array{Float64}}()
是一个值,而不是一个类型(它是指定类型的值)。你愿意我用MWE编辑你的答案吗?对不起,我在打电话,明天早上可以。仅供参考,这种最快的解决方案只是分别定义外部(x)和外部(x,y),而不是依赖默认参数和可空值。我认为这对于您的用例是合适的?例如,如果。。。else
条件作为一个单独的方法,分别使用一个或两个参数它会工作,但我来自
Python
,使用两个重载函数对Python来说是一个丑陋的解决方案!由于您无法包含MWE,我冒昧地编辑了您的答案,然后接受了它。谢谢我查看了
Nullable
类型。但是,我无法让它在函数中工作。你能用
Nullable
类型发布一个MWE来完成你对问题的回答吗(这样我就可以接受你的答案,如果你能让它工作的话)?事实上,我刚刚想出了如何让
Nullable
工作的方法。我在尝试
y::Nullable{Array{Float64}}}=nothing
(这导致了相同的错误),
y::Nullable{Array{Float64}}()
(这会引发
参数错误
),以及
y::Nullable{Array{Float64}}
。解决方案是
y=Nullable{Array{Float64}}()
,因为当我刚才重新阅读文档时,我意识到
Nullable{Array{Float64}}()
是一个值,而不是一个类型(它是指定类型的值)。你愿意我用MWE编辑你的答案吗?对不起,我在打电话,明天早上可以。仅供参考,这种最快的解决方案只是分别定义外部(x)和外部(x,y),而不是依赖默认参数和可空值。我认为这对于您的用例是合适的?例如,如果。。。else
condition作为一个单独的方法,分别使用一个或两个参数,它可以工作,但我来自
Pyth
outer(x::Array{Float64}, y::Array{Float64}) = x .+ y
outer(x::Array{Float64}) = y -> x .* y