英文:
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_Node
和 update!
的定义移至模块内,并导出 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 system
s, if we truncate this at two levels of abstraction), which is a subtype of an abstract type I define in the module. The node
s 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<: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<: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> 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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论