• 让d用户定义效果系统


    std.conv.octal中还有字面.
    不应删除,内置二进制字面.cgi.dvibe.d更快.
    模板化druntime,简单调用dom.d,就够了.

    如果可以在库代码中定义@nogc,pure甚至像@vibe_fiber_safe等等,而不是在编译器中添加,会怎么样?
    我反对@nogc的(许多)批评之一是,它是你想要不解决就能避免特例,类似情况下还会出现类似问题.我一直认为某种用户定义系统会很好,这样它可能会检查多个因素,甚至组合成集合,不必在每个函数上重复十几个属性.AA曾经提出函数的复杂度注解.
    D的内置注解倾向于以禁止列表形式出现.如@nogc函数禁止调用可能调用GC函数的内容,及禁止函数读取静态变量.
    可以想象,标记函数允许及禁止做的事情的系统.内置语言会有一些core.attribute神奇注解说明它们的作用,但也可自定义.
    四种类型的注解:@effect!(...),@denied_effect!(...),@exclusively_allowed_effect!(...)@allowed_hidden_effect!(...).
    D符号标记效果.这允许通过正常模块系统来消歧名空间等.如下:

    // 这是用户定义效果
    enum writes_to_console;
    
    // 函数上声明用户定义效果
    void writeln(string s) @effect!writes_to_console { ... }
    
    // 从编译器访问效果
    import core.effects : gc_allocates;
    
    // 内置的nogc注解因此可成为库别名
    alias nogc = denied_effect!gc_allocates;
    
    import std.typecons : AliasSeq;
    
    // 也可以声明组合
    
    alias no_combined = AliasSeq!(denied_effect!gc_allocates, denied_effect!writes_to_console);
    
    void cant_write_to_console_nor_gc_allocate() @no_combined {
        /*
        编译错误:
            writeln具有writes_to_console效果,但拒绝该效果
        */
        writeln("hi");
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    如果用矛盾东西来标记函数,则是编译错误.

    enum thing;
    
    // 错误!
    void contradiction() @denied_effect!thing @exclusively_allowed_effect!thing {}
    
    • 1
    • 2
    • 3
    • 4

    可用@allowed_hidden_effect来模拟类似内置受信任的东西.

    enum thing;
    
    void foo() @effect!thing {}
    
        //由于调用了`foo()`,它也有与`foo()`相同效果
    void inferred_effect() {
        foo();
    }
    
     //函数调用`foo`,但由于它是允许隐藏的效果`effect!thing`是隐藏的!
    void baz() @allowed_hidden_effect!thing {
        foo();
    }
    
    void error() @denied_effect!thing {
        /*
            这是拒绝效果,但在`推导效果`
            (从调用foo一层深的调用)
        */
        inferred_effect();
    }
    
    void bar() @denied_effect!thing {
        /*
            无误,bar允许隐藏效果
        */
        baz();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    允许和拒绝效果必须与继承一起使用.子类可以拒绝父母允许的事情,但不能允许父母拒绝的事情,就像可添加@nogc覆盖,但不能删除它一样.
    就像内置属性,也希望参数有某种依赖效果.

     //用相对`正常`语法转发效果,神奇的是,它不是在`声明`时静态确定的,而是在`使用`时确定的.
    void map(void delegate() dg) @effect!(__traits(getEffectsOfArgument, dg)) {
        dg();
    }
    
    • 1
    • 2
    • 3
    • 4

    价值在:

    alias fiber_compatible = @denied_effect!blocking
    
    • 1

    主要思想是,如果用户可定义它的,则可做任何需要做的事情.

  • 相关阅读:
    TypeScript基础之模版字面量类型
    如何保证 HTTPS 证书的有效性?
    476.数字的补数
    27、Block-NeRF: Scalable Large Scene Neural View Synthesis
    【JavaScript】基础语法笔记(对比Java)
    数据结构之单链表
    C++ 内存模型
    0070__Postman如何导出接口的几种方法
    每天五分钟机器学习:神经网络模型是如何完成数据训练任务的?
    前端 webpack 面试题
  • 原文地址:https://blog.csdn.net/fqbqrr/article/details/126368415