如何在Julia模块中正确定义和使用全局变量?

4
在Fortran中,我们可以在一个模块中定义全局变量(使用private属性),以便我们可以使用模块中的子例程来设置或更改该变量的值。如下所示:
module Mod
integer, parameter :: r8=selected_real_kind(15,9)
real(kind=r8), private, save :: var
contains
subroutine f(x)
real(kind=r8) :: x
var = 2.0_r8*x
end subroutine f
end

我们可以看到,我们可以调用f(x)并将模块中的变量设置为2x。

现在在Julia中,看起来像下面这样:

module Mod
global var
function f(x::Float64)
global var = 2.0*x
return nothing
end
  1. 我的意思是,如果在函数中变量在左侧,我是否每次都需要指定关键字“global”?

  2. 我还尝试为全局变量指定类型,例如

    global var :: Float64

但是它给了我一个错误。

syntax: type declarations on global variables are not yet supported

看起来我只能什么都不指定,就像这样:

global var

或者在设置其类型的同时给它一个值,
global var=0.0::Float64

在使用全局变量之前,最好为其指定类型。


2
在Fortran世界中,带有副作用的函数被认为是不良的程序实践。你的Fortran代码无效,因为函数结果变量必须在函数返回之前设置。假定r8在某个地方被设置了,但在这里使用时未定义。整数2在浮点数中可以精确表示,所以var = 2 * x比你写的表达式更清晰。最后,在模块的规范部分声明的变量隐含具有save属性,因此real(kind=r8), private, save :: var过于冗长。 - steve
1
@steve r8 显然已经在某处定义了,我没有展示它是因为它不相关,如果你坚持,我可以添加它。我在Fortran中使用子程序而不是函数。子程序不必返回任何值,它只是完成它的工作。最后,你没有对Julia部分提出任何建议。 - CRquantum
2
不使用Julia,因此无法提供如何在其他语言中编写糟糕代码的建议。 - steve
@steve 从你的话中我无法判断你是否能编写高性能Fortran代码。你的评论并不是很有用,因为你只是在重复显而易见的事情。如果你觉得你擅长Fortran,请展示一些你的github Fortran代码或者其他东西,我愿意从中学习。谢谢。 - CRquantum
我不使用GitHub。但是我对Fortran有一些了解。例如,您将var称为全局变量(请使用私有属性)var不是全局的。private属性将var的可见性限制在模块命名空间中。Fortran 2018标准的第19.2节定义了全局标识符,而变量不包括在列表中。 - steve
显示剩余2条评论
1个回答

4

这是一种实现你所需且高效的方法:

julia> const x = Ref(0)
Base.RefValue{Int64}(0)

julia> function f(y)
           x[] = y
       end

f (generic function with 1 method)

julia> x[]
0

julia> f(10)
10

julia> x[]
10

julia> f("10")
ERROR: MethodError: Cannot `convert` an object of type String to an object of type Int64

julia> f(5.0)
5.0

julia> x[]
5

注释:

  1. 我将 x 声明为 const,以确保编译器知道它的类型(这样可以优化代码)。
  2. 我将 x 声明为 Ref,允许其内容可变,并在后面的 x[] = y 语句中清楚地表明 x[] 部分是指全局变量(因为变量 x 没有在 f 的本地作用域中定义)。
  3. 如示例所示,在调用 f 时无法使用 "10",因为它没有匹配的类型。请注意,我可以使用 5.0(浮点数),因为它可以转换为整数。

谢谢!这太棒了!只有一个问题,x[] 中的 [] 是什么意思? - CRquantum
1
这是解决方案的一个要点。x[]表示您正在访问容器x的内容(在此情况下为单个元素容器Ref,因此您无需像数组一样传递索引)。由于您正在访问容器,因此它必须已经存在,因此 Julia 不会尝试创建它。如果您编写了 x =,那么在本地作用域中,Julia 会尝试创建变量 x。如果您编写了 x[] =,则变量 x 必须已经存在,因为您正在访问其内容。这正是您所要求的。 - Bogumił Kamiński

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接