• 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实现一个控制流程。

    ?运算符基本是所有语言都有的一个三目运算符。不过假如没有呢?那么可以考虑利用CPS实现一个库函数达到问好运算符的目的。

    M(B() ? C() : D())
    

    如上函数,我们可以定义一个Conditional函数实现这个逻辑。

    T Conditional<T>(bool b, Func<T> consequence, Func<T> alternative)
    {
        if (b) return consequence(); else return alternative();
    }
    
    //于是可以使用:
    M(Conditional(B(), ()=>C(), ()=>D()))
    

    其他

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

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

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

  • 相关阅读:
    设计模式_抽象工厂模式
    KMeans聚类算法Hadoop实现
    JDK核心JAVA源代码解析(1)
    pushlet单播与多播
    SQL 2008 R2数据库变为REPLICATION,日志不断增长并且不能截断和收缩的解决方式
    chrome插件的popup与跨域请求
    Ubuntu vim+ ctags(包括系统函数) + taglist 配置
    spring Valid @Pattern 常见的验证表达式
    spring boot 全局异常处理
    spring 事件使用
  • 原文地址:https://www.cnblogs.com/mosakashaka/p/12821045.html
Copyright © 2020-2023  润新知