我想说,这属于一个更普遍的已知问题
https://github.com/JuliaLang/julia/issues/15602
.
在您的情况下,考虑一个更简单的函数:
function f()
p() = "before"
println(p())
p() = "after"
nothing
end
打电话
f()
将打印
"after"
.
foo
按以下方式:
julia> @code_typed foo()
CodeInfo(
4 1 â invoke Main.error("Wrong"::String)::Union{} â
â $(Expr(:unreachable))::Union{} â
âââ $(Expr(:unreachable))::Union{} â
) => Union{}
你可以看到Julia优化了所有的内部逻辑,只调用
error
.
如果您提前一步检查,您可以看到:
julia> @code_lowered foo()
CodeInfo(
2 1 â p = %new(Main.:(#p#7)) â
3 â %2 = (p)(1) â
â %3 = %2 != 2 â
âââ goto #3 if not %3 â
4 2 â (Main.error)("Wrong") â
6 3 â return p â
)
你看到了吗
p
在顶行中只指定一次。实际上使用了第二个定义(此处不可见,但可以在上面看到)。
要解决您的问题,请使用以下匿名函数:
function foo2()
p = t -> t + 1
if p(1) != 2
error("Wrong")
end
p = t -> 1
end
一切都会如期进行。这种方法的局限性在于,您不会在name上获得多个dispatch
(它绑定到一个具体的匿名函数,但我猜在您的示例中不需要多次分派)。