如何在Julia lang中初始化复合类型,并在不将其作为函数参数传递的情况下对所有函数进行访问?

如何在Julia lang中初始化复合类型,并在不将其作为函数参数传递的情况下对所有函数进行访问?,julia,Julia,在Julia Lang中,复合类型如何在运行时分配其参数值,并使文件中的所有函数都可以访问 我正在寻找一个类似于Java中“static”关键字的特性。这是为了避免在每次函数调用中发送复合类型,因为它是从一次读取文件初始化的,并且许多函数依赖于它;之后不会更改,但编译时不知道这些值。(我记得Julia中的structs用法,但不确定这是否会改变任何东西) 在Julia中,可以定义全局变量。每个Julia模块(或BareModel)都有其全局范围。 如果您声明了一个全局变量const,那么它的类型

Julia Lang
中,
复合类型如何在运行时分配其参数值,并使文件中的所有函数都可以访问

我正在寻找一个类似于Java中“static”关键字的特性。这是为了避免在每次函数调用中发送复合类型,因为它是从一次读取文件初始化的,并且许多函数依赖于它;之后不会更改,但编译时不知道这些值。(我记得Julia中的structs用法,但不确定这是否会改变任何东西)

  • 在Julia中,可以定义全局变量。每个Julia模块(或BareModel)都有其全局范围。 如果您声明了一个全局变量
    const
    ,那么它的类型可能不会改变(但它与值的绑定可能会改变)
  • 问题的第二部分是这样一个全局常数的可变性。如果全局常量变量的类型是不可变的(例如数字、字符串、
    struct
    s、元组、命名元组),则无法更改其值。但是,仍然可以将变量重新绑定到新值(只要新值具有适当的类型,我们将收到绑定已更改的警告-请参见下面的示例)
  • Julia Base中这种方法的一个很好的例子是
    Base.GLOBAL_RNG
    variable(除了它是可变的)-它在Julia中保持默认随机数生成器的状态

    下面是一个使用
    struct
    的简单示例:

    module E
    
    struct A # immutable
        x::Int
    end
    
    const a = A(1) # global constant in module E
    
    f() = println("a: $a")
    
    function g()
         global a = A(10) # rebinding of a global variable requires global keyword
    end
    
    function h()
        a.x = 100
    end
    
    end # module
    
    如果在REPL中执行此操作,则可以测试行为:

    julia> E.a # we test the value of a global variable in module E
    Main.E.A(1)
    
    julia> E.f() # function f() from this module can access it
    a: Main.E.A(1)
    
    julia> E.h() # we cannot mutate fields of a
    ERROR: type is immutable
    Stacktrace:
     [1] setproperty! at .\sysimg.jl:9 [inlined]
     [2] h() at .\REPL[1]:16
     [3] top-level scope
    
    julia> E.g() # but we can change the binding, we get a warning
    WARNING: redefining constant a
    Main.E.A(10)
    
    julia> E.a
    Main.E.A(10)    
    
    julia> E.a = E.A(1000) # the binding cannot be changed outside the module
    ERROR: cannot assign variables in other modules
    Stacktrace:
     [1] setproperty!(::Module, ::Symbol, ::Main.E.A) at .\sysimg.jl:15
     [2] top-level scope
    
    如果您在REPL中定义了一个全局常量,那么重新绑定它的值还会发出警告(以下是在REPL范围中定义了全局变量的更多示例):

    以下是Julia手册的相关章节:

    • 全球范围:
    • 常数:
    • 复合类型:
    • global
      关键字:
    编辑:在
    g
    函数的定义中添加缺少的
    global
    关键字

  • 在Julia中,可以定义全局变量。每个Julia模块(或BareModel)都有其全局范围。 如果您声明了一个全局变量
    const
    ,那么它的类型可能不会改变(但它与值的绑定可能会改变)
  • 问题的第二部分是这样一个全局常数的可变性。如果全局常量变量的类型是不可变的(例如数字、字符串、
    struct
    s、元组、命名元组),则无法更改其值。但是,仍然可以将变量重新绑定到新值(只要新值具有适当的类型,我们将收到绑定已更改的警告-请参见下面的示例)
  • Julia Base中这种方法的一个很好的例子是
    Base.GLOBAL_RNG
    variable(除了它是可变的)-它在Julia中保持默认随机数生成器的状态

    下面是一个使用
    struct
    的简单示例:

    module E
    
    struct A # immutable
        x::Int
    end
    
    const a = A(1) # global constant in module E
    
    f() = println("a: $a")
    
    function g()
         global a = A(10) # rebinding of a global variable requires global keyword
    end
    
    function h()
        a.x = 100
    end
    
    end # module
    
    如果在REPL中执行此操作,则可以测试行为:

    julia> E.a # we test the value of a global variable in module E
    Main.E.A(1)
    
    julia> E.f() # function f() from this module can access it
    a: Main.E.A(1)
    
    julia> E.h() # we cannot mutate fields of a
    ERROR: type is immutable
    Stacktrace:
     [1] setproperty! at .\sysimg.jl:9 [inlined]
     [2] h() at .\REPL[1]:16
     [3] top-level scope
    
    julia> E.g() # but we can change the binding, we get a warning
    WARNING: redefining constant a
    Main.E.A(10)
    
    julia> E.a
    Main.E.A(10)    
    
    julia> E.a = E.A(1000) # the binding cannot be changed outside the module
    ERROR: cannot assign variables in other modules
    Stacktrace:
     [1] setproperty!(::Module, ::Symbol, ::Main.E.A) at .\sysimg.jl:15
     [2] top-level scope
    
    如果您在REPL中定义了一个全局常量,那么重新绑定它的值还会发出警告(以下是在REPL范围中定义了全局变量的更多示例):

    以下是Julia手册的相关章节:

    • 全球范围:
    • 常数:
    • 复合类型:
    • global
      关键字:

    编辑:在
    g
    函数的定义中添加了缺少的
    global
    关键字。

    @Bogulmil Kaminski,如果我现在想要一个复合类型,每个函数都可以使用相同的值访问它,不管它们是否被传递到复合类型的引用并获得相同的数据,我该怎么做?您想说您有一个复合类型
    a
    ,它有一个字段
    y
    ,并且该字段对于
    a
    和字段
    x
    的每个实例都具有相同的值,这是实例特定的吗?如果是,您可以使用这样的模式
    Base.getproperty(a::a,s::Symbol)=s==:x?getfield(a,:x)?(s==:y?“从某处获取数据”:错误(“没有这样的字段”)
    。字段
    :y
    是静态的,您将其值保存在
    A
    之外的某个位置。您可以类似地定义
    Base.setproperty变异
    y
    。但一般来说,这种模式在Julia中不是典型的设计,我只需要使用第二种类型来存储静态数据。Julia似乎不像Java那样支持这种模式。@Vass我刚刚回答了一个与Fortran相关的问题,我想它可能对您的目的也很有用。。。(该类型还可以包含任何集合类型,如数组,可以在以后的某些函数中动态分配)。@roygvib Yes-这是我的意思的一个很好的例子@Vass同意不能像Java中那样将静态字段混合到Julia中的标准结构中。作为旁注——既然你问过不变性——与Java相反,如果你足够努力,你甚至可以变异不可变对象,例如
    y=ccall(:jl_ptr_to_array,array{Int,1},(Any,ptr{Cvoid},Any,Int32),array{Int,1},ccall(:jl_value_ptr,ptr{Cvoid,(Any,),a,(1,),false)
    。将创建一个可变向量
    y
    ,它允许您在
    y[1]
    指向
    a.x
    时更改
    a.x的值。当然,这不是什么值得推荐的东西。@Bogulmil Kaminski,如果我现在想要一个复合类型,它可以被每个具有相同值的函数访问,不管它们是否被传递到复合类型的引用并获得相同的数据,我该怎么做?你想说你有一个复合类型
    a
    ,它有一个字段
    y
    ,并且这个字段对于
    a
    x的每个实例都有相同的值吗