Julia预定义函数

时间:2019-01-24 14:22:25

标签: julia

我目前正在通过命令行会话在Julia上编程。

我知道Julia中的预定义函数(例如sqrt)可以采用变量值,但是在特定的会话中,我尝试将函数用作sqrt(25),它给了我5.0,但在我写sqrt=9时是同一会话,然后说

  

错误:无法从模块Main分配变量Base.sqrt

如果必须执行此操作,则必须重新打开一个新会话,并为sqrt sqrt=9分配一个变量值,当我这样做时,它会再次显示

  

ERROR:MethodError:Int64类型的对象不可调用

当我尝试使用sqrt作为函数时。

pi也会发生同样的事情。

2 个答案:

答案 0 :(得分:6)

您要询问的主题有些棘手。尽管我同意PilouPili的一般建议,但有时并不那么明显。

您的问题可以分解为两个问题:

  

ERROR:MethodError: objects of type Int64 are not callable

我想这很清楚,如果您有其他编程语言的经验,应该期待。情况是,当前范围内的名称sqrt绑定到值9,并且类型Int64的对象不可调用。

另一个错误

  

"Error: cannot assign variable Base.sqrt from module Main"

更复杂,可能不明显。在调用或引用sqrt函数之前,可以在当前作用域中为自己的变量随意使用名称sqrt。仅在执行此类操作后,才在当前范围内解决与sqrt的绑定(仅最近修复了与https://github.com/JuliaLang/julia/issues/30234有关的一些极端情况的错误)。从这一刻开始,您将无法更改sqrt的值,因为Julia不允许将值分配给从其他模块导入的变量。

Julia手册的相关段落为(https://docs.julialang.org/en/latest/manual/modules/):

  

语句using Lib意味着名为Lib的模块将可用于根据需要解析名称。当遇到在当前模块中没有定义的全局变量时,系统将在Lib导出的变量中搜索该变量并将其导入(如果在该变量中找到)。这意味着当前模块中对该全局变量的所有使用都将解析为Lib中该变量的定义。

  

一旦通过usingimport使变量可见,则模块可能不会创建自己的具有相同名称的变量。导入的变量是只读的;分配给全局变量始终会影响当前模块所拥有的变量,否则会引发错误。

为了更好地理解这些规则的含义,我认为最好用一个例子来说明它们:

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而不是using可以立即解决绑定问题:

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_CONSTANT之类的东西可能会或可能不会被模块定义和导出调用using,在全局范围内首次分配给SOME_CONSTANT的情况下以及第一次阅读SOME_CONSTANT时,Julia代码的行为会有所不同。

最后,在特殊情况下,您想向其他模块中定义的函数添加方法-是否允许,具体取决于您在当前作用域中引入名称的方式,您可以阅读有关详细信息{{3 }}在这种情况下有什么规则。

答案 1 :(得分:2)

Bogumił的回答是正确且准确的,但我认为可以用更简洁的方式来描述。

Julia-与大多数编程语言一样-允许您定义与内置对象同名的 own 变量(或更普遍地,由#include <stdio.h> #include <math.h> int main() { double input; scanf("%lf",&input); int note_100= input/100; int note_50=(fmod(input,100))/50; int note_20=(fmod((fmod(input,100)),50))/20; int note_10=(fmod((fmod((fmod(input,100)),50)),20))/10; int note_5=(fmod((fmod((fmod((fmod(input,100)),50)),20)),10))/5; int note_2=(fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5))/2; int note_1=(fmod((fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5)),2))/1; int note50=(fmod((fmod((fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5)),2)),1))/0.50; int note25=(fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5)),2)),1)),0.50))/0.25; int note10=(fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5)),2)),1)),0.50)),.25))/0.10; int note05=(fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5)),2)),1)),0.50)),0.25)),0.10))/0.05; int note01=(fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod((fmod(input,100)),50)),20)),10)),5)),2)),1)),0.50)),0.25)),0.10)),0.05))/0.01; printf("NOTAS:\n"); printf("%d nota(s) de R$ 100.00\n",note_100); printf("%d nota(s) de R$ 50.00\n",note_50); printf("%d nota(s) de R$ 20.00\n",note_20); printf("%d nota(s) de R$ 10.00\n",note_10); printf("%d nota(s) de R$ 5.00\n",note_5); printf("%d nota(s) de R$ 2.00\n",note_2); printf("MOEDAS:\n"); printf("%d moeda(s) de R$ 1.00\n",note_1); printf("%d moeda(s) de R$ 0.50\n",note50); printf("%d moeda(s) de R$ 0.25\n",note25); printf("%d moeda(s) de R$ 0.10\n",note10); printf("%d moeda(s) de R$ 0.05\n",note05); printf("%d moeda(s) de R$ 0.01\n",note01); return 0; } 包提供) 。这是一件很了不起的事情,因为否则您将不得不翻阅Julia及其软件包提供的数百个名称。

不过有两个问题:

  • 一旦使用了内置名称或任何程序包中的名称,就无法再使用相同的名称(在相同的范围内)定义自己的变量。那就是using:您已经使用过Error: cannot assign variable Base.sqrt from module Main,现在正在尝试定义sqrt(4)。解决方法?只需为变量使用其他名称即可。
  • 您可以使用与内置名称相同的名称来定义自己的变量,也可以使用任何软件包中的名称来定义变量(如果尚未使用的话),但是它将采用您定义的 给它。 sqrt=2就是这种情况:您已经定义了类似ERROR: MethodError: objects of type Int64 are not callable的东西,然后尝试使用sqrt=2。解决方法?您仍然可以通过使用模块名称限定另一个定义来引用它。在这种情况下,sqrt(4)sqrt提供,因此您仍然可以调用Base。您甚至可以重新分配Base.sqrt,以恢复其原始定义。

通过这种方式,sqrt = Base.sqrt和您所Base的其他软件包提供的名称有点像薛定ding的猫:它们处于这种但不是真正的状态,直到你和他们一起做某事。如果先查看它们,则它们存在,但是如果先定义自己的变量,则它们不存在。