Continuation-Passing Style(c#)

Continuation-Passing Style(简写为CPS)是一种代码控制流的实现方式。内容部分来自这里

Continuation

Continuation是指在一个逻辑算法或者功能中,某一计算时刻,之后的所有计算逻辑。
例如

 static void M()
{
    var x = 5;
    F();  // <----------- Point in the computation
    ++x;
    Console.WriteLine(x);
}

static void Main()
{
    M();
    Console.WriteLine("Done");
}

那么在调用F时的Continuation,就是++xConsole.WriteLine(x)

Continuation封装为函数的一个参数,当函数执行完时,不是返回,而是通过调用传入的Continuation传递计算结果,继续往下执行,这种方式就是CPS。

CPS改造

比如取最大值函数

 static int Max(int n, int m)
{
    if (n > m)
        return n;
    else
        return m;
}

转为CPS需要这几步:

  1. 修改返回值类型为void
  2. 添加一个额外的Continuation参数Action<T>, 其中T是函数原本的返回类型。
  3. 用新添加的Continuation参数替换原函数中所有的return语句,传入的参数是原返回值
 static void Max(int n, int m, Action<int> k)
{
    if (n > m)
        k(n);
    else
        k(m);
}

于是原本调用方式也从:

static void Main()

{

    Console.WriteLine(Max(3, 4));

}

变为:

static void Main()

{

    Max(3, 4, x => Console.WriteLine(x));

}

其他

CPS可以是函数更灵活的控制执行流程,实现不同的控制流。c#中的异步(async/await)就使用了CPS实现(以及状态机)。

除此之外,CPS可以可以节省栈内存,因为函数的执行不需要记录返回值,返回值直接通过传入的Continuation进行下一步处理了。

但是CPS写的代码不如普通的控制流容易理解,一遍可能编译器的书写者比较熟悉他的含义。

Continuation-Passing Style(c#)

上一篇:Windows10家庭版安装Docker(不是DockerToolbox)


下一篇:SQL判断是否存在符合某条件的记录