【问题标题】:Ruby blocks/Java closures in CC 中的 Ruby 块/Java 闭包
【发布时间】:2010-09-06 09:33:02
【问题描述】:

我一直在尝试了解 Ruby 块的工作原理,为此我一直在尝试在 C 中实现它们。

实现闭包的一种简单方法是将void* 传递给闭包/函数的封闭堆栈,但Ruby 块似乎也处理使用该块的范围内的返回和中断语句。

loop do
  break i if (i >= 4000)
  i *= 2
end

我认为 Java 的闭包提案之一也是这样工作的。

那么,您将如何在 C 中实现 Ruby 块/Java 闭包?

【问题讨论】:

  • “那么,你将如何在 C 中实现 Ruby-blocks/Java-closures?”至少在 Java 7 发布之前,没有 Java 闭包之类的东西。
  • 是的,这就是为什么我之前说过“Java 的闭包提案”。

标签: java c ruby


【解决方案1】:

闭包的概念需要上下文的概念。 C 的上下文基于 CPU 的堆栈和寄存器,因此要创建块/闭包,您需要能够以正确(和可重入)的方式操作堆栈指针,并根据需要存储/恢复寄存器。

解释器或虚拟机的方式是使用context 结构或类似的结构,而不是直接使用堆栈和寄存器。如果您正在设计基于寄存器的 VM,则此结构会跟踪堆栈和一些寄存器(可选)。至少,这是最简单的方法(虽然比实际正确映射的性能稍差)。

【讨论】:

    【解决方案2】:

    作为“充满激情的 Rails”课程的一部分,有一组关于 Ruby Blocks 的精彩幻灯片:

    Ruby_Blocks.pdf

    这涵盖了表示一个块,它们如何传递参数和执行,甚至更深入到诸如 Proc 对象之类的东西。解释的很清楚。

    然后看看 JRuby 人在解析 Java 时如何处理这些问题可能会很有趣。查看codehaus的源代码。

    【讨论】:

      【解决方案3】:

      我实际上还没有实现任何这些,所以用一袋盐来处理它。

      闭包有两部分:数据环境和代码环境。就像您说的那样,您可能可以传递一个 void* 来处理对数据的引用。您可能可以使用 setjmp 和 longjmp 来实现 Ruby 中断所需的非线性控制流跳转。

      如果您想要闭包,您可能应该使用真正支持它们的语言进行编程。 :-)

      更新:Clang 中正在发生有趣的事情。他们为 C 设计了一个闭包原型。http://lists.cs.uiuc.edu/pipermail/cfe-dev/2008-August/002670.html 可能会被证明是有趣的阅读。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-10
        • 2011-09-02
        • 1970-01-01
        • 2016-02-24
        相关资源
        最近更新 更多