Function 朱莉娅:一个函数对象

Function 朱莉娅:一个函数对象,function,julia,Function,Julia,我想在Julia中使用一个对象,它可以由函数初始化。它就像C中的函数指针。 我的目标是: 我有一个julia脚本和一个julia模块。 在这个脚本中,我有一个数组。 模块需要能够将一些元素添加到此数组中。 #script liste = Int64[] function addElement(e) liste.push(e) end include("path/mymodule.jl") myModule.setAddElementFunc(addElement) myModule.exe

我想在Julia中使用一个对象,它可以由函数初始化。它就像C中的函数指针。

我的目标是:

我有一个julia脚本和一个julia模块。

在这个脚本中,我有一个数组。
模块需要能够将一些元素添加到此数组中。

#script
liste = Int64[]
function addElement(e)
   liste.push(e)
end
include("path/mymodule.jl")
myModule.setAddElementFunc(addElement)
myModule.execute() # error: wrong number of parameter



#mymodule.jl

module myModule
export setAddElementFunc
export execute

addElementFunc = ()->()

funciton setAddElementFunc(fn)
   addElementFunc = fn
end

function execute()
   addElementFunc(3)
end

end
基本上,我的想法是:

在模块中,我们只能执行添加操作。我需要这样一种结构,因为我的工作是编写julia脚本,其他人将编写模块。所以我想限制他的权利来保证列表的安全,在这种情况下,他可以只添加元素。

你想做什么还不完全清楚。 一种可能性是:

function getAddMsgFunc(fn)
  fn  # just return the function that is passed in
end

function my_show()
  println("xxxxx")
end

addMsgFunc = getAddMsgFunc(my_show)

addMsgFunc()

函数在Julia中是一级对象,这意味着您可以通过名称传递它们。

尽管@David完全正确,但我想指出
global
关键字的有用性。我喜欢在这里把它看作是Julia-Lang中的一个CPP
这个类似的关键字

module test
  addMsgFunc=()->()
  function getAddMsgFunc(fn)
    global addMsgFunc = fn
  end
  function show()
    println("xxxxx")
  end
end
julia> addMsgFunc
ERROR: UndefVarError: addMsgFunc not defined
julia> test.addMsgFunc();
julia> test.getAddMsgFunc(test.show);
julia> test.addMsgFunc()
xxxxx
julia> addMsgFunc # Its in global but in another scope
ERROR: UndefVarError: addMsgFunc not defined
julia> test.addMsgFunc=()->() # You cant assign to it normally
ERROR: cannot assign variables in other modules

要在Julia中生成新类型,我们可以执行以下操作

type MyArray{T}
    elements::Vector{T}
    my_value::Int
end
这会自动为您生成两个默认构造函数。 您可以通过为对象的每个字段提供初始值来创建类型的对象

v = MyArray([3, 5], 17)
在Julia中,函数不存在于对象内部,而是在对象外部定义的方法。从这个意义上讲,Julia中的对象与C中的结构相似,只是它们可以(通常应该)按类型参数化,如本例中所示(the
{T}

例如,在这种情况下,您可以简单地定义自己的泛型函数
push从base Julia,对新类型的对象执行操作:

push!(x::MyArray, value) = push!(x.elements, value)
现在你可以做了

push!(v, 4)
将值4添加到对象

您应该阅读Julia手册并查看一些教程,以了解有关定义类型的更多信息。如果有什么不清楚的地方,请告诉我们。

函数指针只是一个复杂的C结构,这是必需的,因为没有其他方法可以使用不同的名称来引用函数

在Julia中,您只需创建另一个名称来引用相同的函数对象,正如我在第一个答案中所做的,例如

hello() = "hi"
goodbye() = "ciao"

f = hello   # f is a "function pointer"
f()

f = goodbye
f()
您可以轻松地将函数放入其他数据结构中,例如字典:

greeting = Dict("hello" => hello, "goodbye" => goodbye)

f = greeting["hello"]
f()

谢谢。只有一个问题:如果show()有一个参数,如何更改
addMsgFunc=()->()
?模块级没有类型检查,因此不要将其视为
cpp
类,并且
addMsgFunc=()->()
不像初始值设定项那样工作,实际上您不需要它。我认为你的问题是一个误解的迹象。在我看来,使用这样一个全球性的方法是一个非常糟糕的主意。这是“联合国朱利安”,将是缓慢的。这也使得对代码进行推理变得非常困难,因为任何人都可以从任何地方修改全局变量。也许你想要的是在用户定义的类型中嵌入一个函数?@David,我部分同意你的观点,请查看最新的编辑PLZ查看我的最新编辑。我根本不想使用任何全局变量,但我不知道如何生成用户定义的类型,类似于cpp中的类。我对Julia完全是个新手。
global addElementFunc=fn
还有
function execute(arg::Tuple)addElementFunc(arg…)end
@RezaAfzalan除了
arg…
还有其他方法吗。我更喜欢在C中使用类似对象的函数指针。
addElementFunc(arg…===apply(addElementFunc,arg)
@RezaAfzalan-aha,这是个好主意。非常感谢,非常感谢。我抓到你了。我读过一些教程,但我仍然不知道如何声明函数对象,比如C中的函数指针。现在,我喜欢这样做:在模块中,
函数执行(fn1,fn2)
;在脚本中,我可以调用
myModule.execute(addElement,setElement)
addElement
setElement
是脚本中的两个函数。它起作用了。所以我不再需要任何函数指针了。如果您知道如何在Julia中声明函数指针,请告诉我:D非常感谢。