JuliaDo函数的语法是如何工作的?

我在这里看到do语法可以用作编写map()函数的更方便的方法,但我不明白例如在链接的 julia 文档中显示的示例中:

open("outfile", "w") do io
    write(io, data)
end

它适用于“打开”的以下函数定义

function open(f::Function, args...)
    io = open(args...)
    try
        f(io)
    finally
        close(io)
    end
end

如何在世界上没有的do传递iowrite(io,data)到的实际功能openf(io)?具有do块的函数是否必须具有相同的名称/被多次调度才能使do块工作?

回答

这是一个纯粹的句法转换。

func(x) do y
    body
end

相当于

func(y -> body, x)

或者

tmp = y -> body
func(tmp, x)

如果你愿意,即do块定义了一个匿名函数,作为第一个参数传递。为此,当然,需要存在一种func具有匹配签名的方法,例如func(f::Function, ...) = ...(或简单地func(f, ...) = ...)。


您可以使用以下命令检查实际发生的情况Meta.@lower

julia> Meta.@lower func(x) do y
           print(y)
       end
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ?      $(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ?      global var"#1#2"
?        const var"#1#2"
?   %3 = Core._structtype(Main, Symbol("#1#2"), Core.svec(), Core.svec(), false, 0)
?        var"#1#2" = %3
?        Core._setsuper!(var"#1#2", Core.Function)
?        Core._typebody!(var"#1#2", Core.svec())
???      return nothing
)))
?   %2 = Core.svec(var"#1#2", Core.Any)
?   %3 = Core.svec()
?   %4 = Core.svec(%2, %3, $(QuoteNode(:(#= REPL[1]:2 =#))))
?        $(Expr(:method, false, :(%4), CodeInfo(
    @ REPL[1]:2 within `none'
1 ? %1 = print(y)
???      return %1
)))
?        #1 = %new(var"#1#2")
?   %7 = #1
?   %8 = func(%7, x)
???      return %8
))))

不幸的是,输出中包含匿名函数的实现细节:代码定义了一个新的 struct ( %3),%4使用do块体使其可调用 ( ) ,创建它的实例 ( %7),最后调用func(%7, x).


以上是JuliaDo函数的语法是如何工作的?的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>