朱莉娅模块调用用户定义函数

huangapple go评论77阅读模式
英文:

Julia Module calling User Defined Function

问题

抱歉,我注意到你要求只翻译代码部分,这是你提供的代码的翻译:

我有一个模块,用于为我想要执行的仿真建立一些抽象级别。假设最低的抽象级别是 `node`(如果我们将其截断为两个抽象级别,我们将其构建为 `system`),它是我在模块中定义的抽象类型的子类型。`node` 使用用户定义的 `update!` 函数进行更新。

我希望用户能够定义一个新的 `node``update!` 函数,但 `update!` 函数应该可以从模块的 `system_update!` 函数中调用。下面提供了一个示例:

```# 定义模块
module test_pack
abstract type Node end

struct System{N<:Node}
    nodes::Array{N,1}
end

function system_update!(s::System)
   update!.(s.nodes) 
end

export Node, System, system_update!
end


# 导入模块
using Main.test_pack


# 用户定义的类型和函数
mutable struct My_Node<:Node
    state
end
function update!(n::My_Node)
   n.state *= 2 
end


# 定义用户定义节点的系统
sys = System([My_Node(1), My_Node(2)])

# 运行系统
system_update!(sys)

运行此代码会出现以下错误:

ERROR: LoadError: UndefVarError: update! not defined

但是,如果我将 My_Nodeupdate! 的定义移至模块内,并导出 My_Node,则代码会执行并返回适当的输出 2,4

是否有一种方法可以启用我期望的行为,即用户定义类型和 update! 函数,但模块定义的 System 可以调用这些函数?

英文:

I have a module which builds up some levels of abstraction for a simulation I'd like to perform. Let's say the lowest level of abstraction is a node (which we build into systems, if we truncate this at two levels of abstraction), which is a subtype of an abstract type I define in the module. The nodes are updated with a user-defined update! function.

I want the user to be able to define a new node and update! function, but the update! function should be callable from the module's system_update! function. An example is provided below:

module test_pack
abstract type Node end

struct System{N<:Node}
    nodes::Array{N,1}
end

function system_update!(s::System)
   update!.(s.nodes) 
end

export Node, System, system_update!
end


# import module
using Main.test_pack


# User-defined types and functions
mutable struct My_Node<:Node
    state
end
function update!(n::My_Node)
   n.state *= 2 
end


# Define system of user defined nodes
sys = System([My_Node(1), My_Node(2)])

# Run the system
system_update!(sys)

Running this code gives

ERROR: LoadError: UndefVarError: update! not defined

However, if I move the definition of My_Node and update! to within the module and then export My_Node, the code executes and return the appropriate 2,4 output.

Is there a way I can enable the type of behavior I expect, where the user defines the type and update! function, but the module-defined System can call those functions?

答案1

得分: 4

以下是翻译好的部分:

一种实现你想要的方式是,通过这样的方式设置,即由模块定义update! 函数,定义My_Node类型的代码(派生自Node)也定义了一个特定的方法,扩展了update!函数。

在这里,由于没有针对抽象类型Node的参数的update!的默认实现,可以定义一个空的通用函数,仅将函数标记为属于模块,而不提供任何实现。实现TestPack.update!(::My_Node)方法明确扩展了这个函数,通过完全限定的名称引用它。

module TestPack
abstract type Node end

struct System{N<:Node}
    nodes::Array{N,1}
end

function update! end

function system_update!(s::System)
    update!.(s.nodes)
end

export Node, System, system_update!
end

# 导入模块
using .TestPack

# 用户定义的类型和函数
mutable struct My_Node<:Node
    state
end

function TestPack.update!(n::My_Node)
    n.state *= 2
end

sys = System([My_Node(1), My_Node(2)])

# 运行系统
system_update!(sys)

上面的代码可以正常运行并产生以下结果:

julia> sys
System{My_Node}(My_Node[My_Node(2), My_Node(4)])

另外,值得一提的是,在Julia中,习惯使用CamelCase表示模块的名称;在上面的示例中,我将你的模块重命名为TestPack,以遵循这个风格约定

模块也可以被称为using .TestPack而不是using Main.TestPack,这被称为相对模块路径

英文:

One way of doing what you want would be to set things up in such a way that the update! function is defined by the module, and the code which defines the My_Node type (deriving from Node) also defines a specific method extending the update! function.

Here, since there is no default implementation for update! working on an argument of abstract type Node, an empty generic function can be defined to only mark the function as "belonging" to the module, without providing any implementation.<br/>
The implementation of the TestPack.update!(::My_Node) method explicitly extends this function, referring to it via a fully qualified name.

module TestPack
abstract type Node end

struct System{N&lt;:Node}
    nodes::Array{N,1}
end

function update! end

function system_update!(s::System)
    update!.(s.nodes)
end

export Node, System, system_update!
end


# import module
using .TestPack


# User-defined types and functions
mutable struct My_Node&lt;:Node
    state
end

function TestPack.update!(n::My_Node)
    n.state *= 2
end


sys = System([My_Node(1), My_Node(2)])

# Run the system
system_update!(sys)

The code above runs without problem and yields:

julia&gt; sys
System{My_Node}(My_Node[My_Node(2), My_Node(4)])

As an aside, note that it is customary in Julia to use CamelCase notations for the name of modules; in the example above, I renamed your module to TestPack to follow this stylistic convention.

The module can also be referred to as using .TestPack instead of using Main.TestPack; this is called a relative module path.

huangapple
  • 本文由 发表于 2020年1月4日 01:15:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/59582667.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定