我正在尝试理解一段相对简单的代码,但我无法完全解释发生了什么(我是一个来自Python/Matlab背景的朱莉娅新手)。
function myfunc(number::Integer)
double() = 2*number
square() = number^2
return _ -> (number, double, square)
end据我所知,myfunc正在返回一个匿名函数,它不关心传递给它的值。所以这些案子对我来说是有意义的:
julia> n4 = myfunc(4)
#9 (generic function with 1 method)
julia> n4(50)
(4, var"#double#10"{Int64}(4), var"#square#11"{Int64}(4))在第一行中,n4引用匿名函数本身,而在第二行,使用参数50调用匿名函数,并执行它应该做的事情:丢弃50并返回包含用其定义的数据的元组。
我不明白的是我是如何做到的:
julia> n4.square
(::var"#square#11"{Int64}) (generic function with 1 method)
julia> n4.square()
16引用匿名函数的n4有子对象n4.number、n4.double、n4.square,这对我来说是个惊喜。n4是如何表现的,就好像它是一个结构?将n4(*)[2]()作为答案返回8是有意义的,但是当fieldnames(n4)失败时,在幕后发生了一些我不明白如何使n4.double()工作的事情。在n4之后,我能够使用n4来获取函数/数据的机制是什么?
发布于 2020-05-26 08:54:40
在Julia中,所有的泛型函数(即所有正规的Julia定义函数)都是结构函数.任何结构都可以在Julia中被调用,因此在默认情况下,一个正常函数只是一个零域结构(一个单例结构)。换句话说,做
foo(x) = x+1
类似于
struct Foo end
const foo = Foo()
(::Foo)(x) = x + 1这对于普通函数非常有用,但是对于匿名函数来说,这会导致大量新类型的创建。例如,您可以这样做:functions = [x -> x+i for i in 1:1000]。
朱莉娅没有创建1000个新类型(每个类型都有一个新的i值),而是创建了一个包含i字段的类型和1000个实例。
在您的示例中,它不是myfunc为每次调用返回一个新类型并返回该类型的单例实例,而是返回一个类型的实例,其中包含number、double和square字段。
另外,您完全可以调用字段名,只需在一个类型:fieldnames(typeof(myfunc(4)))上调用它。
这只是一种优化,您的代码依赖于函数在内存中的表示方式,这让人感到有点奇怪。你也许不该这么做。
https://stackoverflow.com/questions/62017689
复制相似问题