Julia预定义函数
我目前正在通过命令行会话在Julia上编程 我知道Julia中的预定义函数(例如sqrt)可以具有可变值,但在特定会话中,我尝试将该函数用作Julia预定义函数,julia,Julia,我目前正在通过命令行会话在Julia上编程 我知道Julia中的预定义函数(例如sqrt)可以具有可变值,但在特定会话中,我尝试将该函数用作sqrt(25),它给了我5.0,但在同一会话中,当我编写sqrt=9时,它说 “错误:无法从主模块分配变量Base.sqrt” 如果我必须实现这一点,我必须重新打开一个新会话,并为sqrtsqrt=9指定一个变量值,当我这样做时,它会再次显示 ERROR:MethodError:Int64类型的对象不可调用 当我尝试使用sqrt作为函数时 同样的事情也发生
sqrt(25)
,它给了我5.0
,但在同一会话中,当我编写sqrt=9
时,它说
“错误:无法从主模块分配变量Base.sqrt”
如果我必须实现这一点,我必须重新打开一个新会话,并为sqrtsqrt=9指定一个变量值,当我这样做时,它会再次显示
ERROR:MethodError:Int64类型的对象不可调用
当我尝试使用sqrt作为函数时
同样的事情也发生在pi
上 你要问的话题有点棘手。虽然我同意委员会的一般建议,但有时并不那么明显
您的问题可以分解为两个问题:
ERROR:MethodError:Int64类型的对象不可调用
我想,这一点非常清楚,如果您有其他编程语言的经验,这一点应该是意料之中的。这种情况是,当前范围中的namesqrt
绑定到value9
,类型为Int64
的对象不可调用
另一个错误
“错误:无法从主模块分配变量Base.sqrt”
更复杂,可能不明显。在调用或引用sqrt
函数之前,您可以在当前范围内为自己的变量自由使用namesqrt
。只有在这些操作之后,sqrt
的绑定才会在当前范围内得到解决(只是最近一些与何时解决绑定相关的死角错误才得到修复)。从现在起,您不允许更改sqrt
的值,因为Julia不允许为从其他模块导入的变量赋值
Julia手册中的相关段落如下():
语句使用Lib
意味着名为Lib
的模块将可用于根据需要解析名称。当遇到在当前模块中没有定义的全局变量时,系统将在Lib
导出的变量中搜索该全局变量,如果找到该全局变量,则将其导入。这意味着当前模块中对该全局变量的所有使用将解析为Lib
中该变量的定义
及
通过使用
或导入
使变量可见后,模块可能无法使用相同的名称创建自己的变量。导入的变量是只读的;分配给全局变量始终会影响当前模块拥有的变量,否则会引发错误
为了更好地理解这些规则的含义,我认为最好用一个例子来说明:
julia> module A
export x, y
x = 10
y = 100
end
Main.A
julia> using .A
julia> x = 1000
1000
julia> y
100
julia> y = 1000
ERROR: cannot assign variable A.y from module Main
另一方面,通过显式调用import
而不是使用可以立即解析绑定:
julia> module A
export x, y
x = 10
y = 100
end
Main.A
julia> import .A: x, y
julia> x = 1000
ERROR: cannot assign variable A.x from module Main
您可以看到,它不是特定于Base
或函数的东西,而是任何模块和任何变量。实际上,在实践中可能会遇到这个问题,因为很明显,sqrt
是一个预定义的函数,但是像SOME\u CONSTANT
这样的东西可能会也可能不会由您使用
on调用的模块定义和导出,并且在您第一次在全局范围内分配SOME\u CONSTANT
时和您第一次读取SOME\u CONSTANT
时,Julia代码的行为会有所不同
最后,有一种特殊情况,当您想向另一个模块中定义的函数添加方法时-这是允许的还是不允许的,这取决于您在当前范围中如何引入名称,您可以阅读详细信息,在这种情况下,规则是什么。Bogumił的回答是正确的,但我认为可以更简洁地描述它
Julia—与大多数编程语言一样—允许您使用与内置内容相同的名称定义自己的变量(或者更一般地说,由使用
包提供)。这是一件很棒的事情,因为如果不是这样,你就必须对Julia及其软件包提供的数百个名字指手画脚
不过,有两个陷阱:
- 一旦使用了内置名称或任何包中的名称,就不能再使用相同的名称(在相同的范围内)定义自己的变量。这就是
错误:无法从模块Main分配变量Base.sqrt
:您已经使用了sqrt(4)
,现在正在尝试定义sqrt=2
。解决办法?只需为变量使用不同的名称即可
- 您可以使用与内置名称相同的名称来定义自己的变量,如果您还没有使用任何包中的名称,则可以使用该名称来定义自己的变量,但随后它将接受您给定的定义。
ERROR:MethodError:Int64类型的对象是不可调用的
:您定义了类似于sqrt=2
的内容,然后尝试使用sqrt(4)
。解决办法?您仍然可以通过使用其他定义的模块名对其进行限定来引用该定义。在这种情况下,sqrt
由Base
提供,因此您仍然可以调用Base.sqrt
。您甚至可以重新分配sqrt=Base.sqrt
,以恢复其原始定义
通过这种方式,Base
和您正在使用的其他包提供的名称有点像薛定谔猫:它们处于这种状态,但在您对它们做一些操作之前,它们并不是真正的状态。如果先看它们,它们就存在,但如果先定义自己的变量,它们就不存在。我真的不理解这个问题。你所描述的似乎是预期的行为。如果要避免这种情况,请使用Base.sqrt,而不是使用sqrt或