gpt4 book ai didi

closures - Julia (Julia)带let封口-是犹太洁食?

转载 作者:行者123 更新时间:2023-12-03 16:56:40 34 4
gpt4 key购买 nike

我使用let块将Julia中的闭包拼凑在一起。

counter = let
local counter = 0 # local variable
f() = counter += 1 # returned function
end

counter(); counter(); counter()
print(counter()) # 4
这是 Julia 的犹太洁食吗?

最佳答案

这是有效的。这是获得相似事物的两种替代方法:

julia> function get_counter()
counter = 0
return () -> (counter += 1)
end
get_counter (generic function with 1 method)

julia> c1 = get_counter()
#1 (generic function with 1 method)

julia> c1()
1

julia> c1()
2

julia> c1()
3

julia> mutable struct Counter
counter::Int
Counter() = new(0)
end

julia> (c::Counter)() = (c.counter += 1)

julia> c2 = Counter()
Counter(0)

julia> c2()
1

julia> c2()
2

julia> c2()
3
区别在于 c2是类型稳定的,而您的 counterc1不是类型稳定的:
julia> @code_warntype counter()
Variables
#self#::var"#f#1"
counter::Union{}

Body::Any
1 ─ %1 = Core.getfield(#self#, :counter)::Core.Box
│ %2 = Core.isdefined(%1, :contents)::Bool
└── goto #3 if not %2
2 ─ goto #4
3 ─ Core.NewvarNode(:(counter))
└── counter
4 ┄ %7 = Core.getfield(%1, :contents)::Any
│ %8 = (%7 + 1)::Any
│ %9 = Core.getfield(#self#, :counter)::Core.Box
│ Core.setfield!(%9, :contents, %8)
└── return %8

julia> @code_warntype c1()
Variables
#self#::var"#2#3"
counter::Union{}

Body::Any
1 ─ %1 = Core.getfield(#self#, :counter)::Core.Box
│ %2 = Core.isdefined(%1, :contents)::Bool
└── goto #3 if not %2
2 ─ goto #4
3 ─ Core.NewvarNode(:(counter))
└── counter
4 ┄ %7 = Core.getfield(%1, :contents)::Any
│ %8 = (%7 + 1)::Any
│ %9 = Core.getfield(#self#, :counter)::Core.Box
│ Core.setfield!(%9, :contents, %8)
└── return %8

julia> @code_warntype c2()
Variables
c::Counter

Body::Int64
1 ─ %1 = Base.getproperty(c, :counter)::Int64
│ %2 = (%1 + 1)::Int64
│ Base.setproperty!(c, :counter, %2)
└── return %2
counter::Int = 0counter定义中添加 c1将使其类型稳定,但是无论如何,您都可以让Julia进行装箱/拆箱。因此,总的来说,我通常会选择使用仿函数( c2版本)。另外,您可以使用 c1包装器来使您的(或 Ref)版本类型稳定:
julia> counter = let
local counter = Ref(0) # local variable
f() = counter[] += 1 # returned function
end
(::var"#f#1"{Base.RefValue{Int64}}) (generic function with 1 method)

julia> counter()
1

julia> counter()
2

julia> counter()
3

julia> @code_warntype counter()
Variables
#self#::var"#f#1"{Base.RefValue{Int64}}

Body::Int64
1 ─ %1 = Core.getfield(#self#, :counter)::Base.RefValue{Int64}
│ %2 = Base.getindex(%1)::Int64
│ %3 = (%2 + 1)::Int64
│ %4 = Core.getfield(#self#, :counter)::Base.RefValue{Int64}
│ Base.setindex!(%4, %3)
└── return %3

关于closures - Julia (Julia)带let封口-是犹太洁食?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64512168/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com