如何在 Julia 中获取 `do` 块的值?
How do get values of out a `do` block in Julia?
我有一个 HDF5 文件,我想从中读取 2 个数组。我怎样才能使用 do
块表示法得到它们?
using HDF5
function myfunc()
h5open("path", "r") do f
a = read(f, "a")
b = read(f, "b")
end
# ... do some more processing of a, b
return a, b
end
如果我运行那个,它会在a not defined
的do块之后出错。我如何获取这些值以便我可以在之后处理它们,而不用将完整的计算包装在 do
块中?
A do
块只是用于创建作为第一个参数传递的匿名函数的语法(在本例中为 h5open
)。就像常规函数一样,您需要 return 来自要在“外部”使用的匿名函数的任何值:
# Function to mimic Base.open, HDF5.h5open etc
function open(f)
return f()
end
function g()
a, b = open() do
c = "hello"
d = "world"
return c, d # returns from the "do"-anonymous function
end
return a, b
end
您可以像这样在外部函数中定义 local
变量:
julia> function f()
local a, b
map(10) do x
a = x + 1
b = x + 2
end
return a, b
end
f (generic function with 1 method)
julia> f()
(11, 12)
这种方法的缺点是编译器无法在所有情况下使其类型稳定,并且还可能装箱 a
和 b
(这两种情况都发生在我的示例中)。 @fredrikekre 提出的是一种首选方法 AFAICT。参见:
julia> @code_warntype f()
Variables
#self#::Core.Compiler.Const(f, false)
b@_2::Core.Box
a@_3::Core.Box
#1::var"#1#2"
a@_5::Union{}
b@_6::Union{}
Body::Tuple{Any,Any}
1 ─ (b@_2 = Core.Box())
│ (a@_3 = Core.Box())
│ (#1 = %new(Main.:(var"#1#2"), b@_2, a@_3))
│ %4 = #1::var"#1#2"
│ Main.map(%4, 10)
│ %6 = Core.isdefined(a@_3, :contents)::Bool
└── goto #3 if not %6
2 ─ goto #4
3 ─ Core.NewvarNode(:(a@_5))
└── a@_5
4 ┄ %11 = Core.getfield(a@_3, :contents)::Any
│ %12 = Core.isdefined(b@_2, :contents)::Bool
└── goto #6 if not %12
5 ─ goto #7
6 ─ Core.NewvarNode(:(b@_6))
└── b@_6
7 ┄ %17 = Core.getfield(b@_2, :contents)::Any
│ %18 = Core.tuple(%11, %17)::Tuple{Any,Any}
└── return %18
我有一个 HDF5 文件,我想从中读取 2 个数组。我怎样才能使用 do
块表示法得到它们?
using HDF5
function myfunc()
h5open("path", "r") do f
a = read(f, "a")
b = read(f, "b")
end
# ... do some more processing of a, b
return a, b
end
如果我运行那个,它会在a not defined
的do块之后出错。我如何获取这些值以便我可以在之后处理它们,而不用将完整的计算包装在 do
块中?
A do
块只是用于创建作为第一个参数传递的匿名函数的语法(在本例中为 h5open
)。就像常规函数一样,您需要 return 来自要在“外部”使用的匿名函数的任何值:
# Function to mimic Base.open, HDF5.h5open etc
function open(f)
return f()
end
function g()
a, b = open() do
c = "hello"
d = "world"
return c, d # returns from the "do"-anonymous function
end
return a, b
end
您可以像这样在外部函数中定义 local
变量:
julia> function f()
local a, b
map(10) do x
a = x + 1
b = x + 2
end
return a, b
end
f (generic function with 1 method)
julia> f()
(11, 12)
这种方法的缺点是编译器无法在所有情况下使其类型稳定,并且还可能装箱 a
和 b
(这两种情况都发生在我的示例中)。 @fredrikekre 提出的是一种首选方法 AFAICT。参见:
julia> @code_warntype f()
Variables
#self#::Core.Compiler.Const(f, false)
b@_2::Core.Box
a@_3::Core.Box
#1::var"#1#2"
a@_5::Union{}
b@_6::Union{}
Body::Tuple{Any,Any}
1 ─ (b@_2 = Core.Box())
│ (a@_3 = Core.Box())
│ (#1 = %new(Main.:(var"#1#2"), b@_2, a@_3))
│ %4 = #1::var"#1#2"
│ Main.map(%4, 10)
│ %6 = Core.isdefined(a@_3, :contents)::Bool
└── goto #3 if not %6
2 ─ goto #4
3 ─ Core.NewvarNode(:(a@_5))
└── a@_5
4 ┄ %11 = Core.getfield(a@_3, :contents)::Any
│ %12 = Core.isdefined(b@_2, :contents)::Bool
└── goto #6 if not %12
5 ─ goto #7
6 ─ Core.NewvarNode(:(b@_6))
└── b@_6
7 ┄ %17 = Core.getfield(b@_2, :contents)::Any
│ %18 = Core.tuple(%11, %17)::Tuple{Any,Any}
└── return %18