我正在尝试做这样的事情:
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,其中x
是data
而y
是模型的parameter
。我试图在模型的参数中返回一个函数以使用MLE进行优化,或者在参数传递时返回log-sum。
在这个类比中,outer
计算log-sum,给定数据和参数,或者返回inner
作为参数的函数,可以对其进行优化。
答案 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
。
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