如何将Julia中的任何函数重置为其原始状态



我正在学习Julia,这是我无法理解的。

案例1:我启动了Julia控制台,并用数字10覆盖了默认的sqrt函数。所以现在这个函数不起作用了。对于来自R的我来说,这有点令人惊讶,在R中,通常即使我们重写一个函数,它也会因为方法调度而起作用。很明显,Julia做这件事的方式不同,这没关系。但现在我无法恢复到它的自然状态。我必须重新启动Julia才能使它(sqrt)再次工作。

julia> sqrt = 10
10
julia> sqrt(5)
ERROR: MethodError: objects of type Int64 are not callable
Stacktrace:
[1] top-level scope at REPL[2]:1
julia> sqrt = Nothing
Nothing
julia> sqrt(5)
ERROR: MethodError: no method matching Nothing(::Int64)
Closest candidates are:
Nothing() at boot.jl:324
Stacktrace:
[1] top-level scope at REPL[4]:1

案例2:我启动了Julia控制台,并使用sqrt函数来计算事情,它成功了。但现在,如果我试图重置为常数,它就不起作用了。(我之所以假设它,是因为它已经编译,因此不能重写)。

julia> sqrt(7)
2.6457513110645907
julia> sqrt = 10
ERROR: cannot assign a value to variable Base.sqrt from module Main
Stacktrace:
[1] top-level scope at REPL[2]:1

我的问题是

有没有办法在不重新启动Julia的情况下将功能重置为原始状态?此外,我对案例2的假设是否正确

我不确定它是否已经在某个地方得到了答案。我试着找到它,但没能找到。我还在读这件事。但如果有人知道这一点,请寻求帮助。提前谢谢。

AFAIU,这种行为的基本原理如下:

  1. 当您在程序中运行sqrt(5)时,这意味着您了解sqrt函数。如果以后您试图为sqrt分配一个新值,Julia会禁止您这样做,因为程序中的sqrt实际上引用了Base.sqrt函数,它是一个常量。(请注意,由using包导出的任何函数也是如此;这里没有与Base相关的特殊性,只是您不必显式地using Base才能调用它定义的函数)。

  2. 如果你不首先使用sqrt作为函数,Julia就不能假设你知道Base.sqrt。因此,如果程序中第一次提到sqrt是一个赋值,它会很高兴地创建一个同名的新变量。这使Julia更加经得起未来的考验:假设您编写了一个声明并使用名为foo的变量的程序。截至Julia 1.5.3,不存在Base.foo函数。但是现在假设Julia1.6引入了一个Base.foo函数。我们不希望这样的更改破坏您现有的代码,这些代码应该继续使用较新的Julia版本。因此,在这种情况下,安全的选择是允许您自由声明变量foo,而不必担心与Base.foo的名称冲突。

现在,如果您在交互式会话中意外创建了一个与现有函数冲突的全局变量,一个简单的解决方案是简单地将您的变量重新分配给Base中的函数(或原始函数来自的任何模块):

julia> sqrt = 1
1
# Oops, looks like I made a mistake
julia> sqrt(2)
ERROR: MethodError: objects of type Int64 are not callable
Stacktrace:
[1] top-level scope at REPL[2]:1
# Let's try and fix it
julia> sqrt = Base.sqrt
sqrt (generic function with 20 methods)
julia> sqrt(2)
1.4142135623730951

最新更新