简短的回答是,continuation由堆分配的对象表示.当您执行使用延续传递样式编写的代码时,表示延续的对象树(在堆上)会增长.
但是,continuation不存储要运行的代码 - 它只存储闭包(代码使用的变量和其他状态).由continuation树中的每个节点执行的代码始终是相同的(并且它以与普通.NET方法相同的方式存储).
假设我们有一些非常简单的东西:
let rec factorial n c = if n = 0 then c 1 else factorial (n - 1) (fun r -> c (r * n))
在3个递归步骤之后factorial 3 id
,该c
值将是堆分配的对象,如下所示:
+--------+ +--------+ +--------+ | n = 1 | / | n = 2 | / | n = 3 | | c = ----/ | c = ----/ | c = id | +--------+ +--------+ +--------+
因此,如果我的ASCII艺术有意义,我们有3个已分配的对象,这些对象包含继续运行函数体所需的值.也就是说,前一个c
值和n
当前迭代的值.
简短的回答是,continuation由堆分配的对象表示.当您执行使用延续传递样式编写的代码时,表示延续的对象树(在堆上)会增长.
但是,continuation不存储要运行的代码 - 它只存储闭包(代码使用的变量和其他状态).由continuation树中的每个节点执行的代码始终是相同的(并且它以与普通.NET方法相同的方式存储).
假设我们有一些非常简单的东西:
let rec factorial n c = if n = 0 then c 1 else factorial (n - 1) (fun r -> c (r * n))
在3个递归步骤之后factorial 3 id
,该c
值将是堆分配的对象,如下所示:
+--------+ +--------+ +--------+ | n = 1 | / | n = 2 | / | n = 3 | | c = ----/ | c = ----/ | c = id | +--------+ +--------+ +--------+
因此,如果我的ASCII艺术有意义,我们有3个已分配的对象,这些对象包含继续运行函数体所需的值.也就是说,前一个c
值和n
当前迭代的值.