使用D字符串mixins进行代码重用是一种反模式吗?

dsi*_*cha 7 d anti-patterns cut-and-paste

对于那些不熟悉D字符串mixins的人来说,它们基本上是编译时间的.您可以获取任何编译时字符串(无论是文字还是通过模板元编程或编译时函数评估生成)并将其编译为代码.如果你使用一个简单的字符串文字,它基本上是编译器自动复制粘贴.

您是否认为使用字符串混合文字作为简单代码重用的方法是反模式,而其他分解方法不太合适?一方面,它基本上是编译器自动化的文字复制和粘贴,这意味着一旦混合在实例中就没有任何关系.如果字符串mixin中的符号与混合范围中的符号发生碰撞,则会发生错误(尽管在编译时,而不是在运行时).它是相对非结构化的,例如,可以将一个字符串混合到一个函数的中间,当且仅当范围中的变量根据某个约定命名时才会起作用.Mixins还可以声明外部作用域随后可以使用的变量.

另一方面,因为复制和粘贴是编译器自动化的,所以在源代码级别的代码有一个单一的真实点,如果需要修改它,它只需要在一个地方修改,一切都保持同步.字符串mixins还大大简化了重用代码,这些代码很难以任何其他方式考虑因素,否则很有可能被手动剪切和粘贴.

Fee*_*ure 11

你提出的所有批评都是正确的.

无论如何,它仍然优于手动copypaste.

实际上,我在我的工具库,字符串表扩展中运行了类似的东西.示例代码,来自路径跟踪器的动态值实现:

  T to(T)() {
    static if (!is(T == Scope)) {
      T value;
      if (flatType == FlatType.ScopeValue) value = sr.value().to!(T);
    }
    const string Table = `
                 | bool          | int         | string               | float   | Scope
      -----------+---------------+-------------+----------------------+---------+----------
      Boolean    | b             | b           | b?q{true}p:q{false}p | ø       | ø
      Integer    | i != 0        | i           | Format(i)            | i       | ø
      String     | s == q{true}p | atoi(s)     | s                    | atof(s) | ø
      Float      | ø             | cast(int) f | Format(f)            | f       | ø
      ScopeRef   | !!sr          | ø           | (sr?sr.fqn:q{(null:r)}p) | ø   | sr
      ScopeValue | value         | value       | value                | value   | sr`;
    mixin(ctTableUnrollColMajor(Table,
      `static if (is(T == $COL))
        switch (flatType) {
          $BODY
          default: throw new Exception(Format("Invalid type: ", flatType));
        }
      else `,
      `case FlatType.$ROW:
        static if (q{$CELL}p == "ø")
          throw new Exception(q{Cannot convert $ROW to $COL: }p~to!(string)~q{! }p);
        else return $CELL;
      `
    ).litstring_expand() ~ `static assert(false, "Unsupported type: "~T.stringof); `);
  }
Run Code Online (Sandbox Code Playgroud)

我敢肯定很容易看出嵌套的ifs和case语句是多么糟糕,多余的混乱,没有字符串mixins - 这样,所有的丑陋都集中在底层,而且函数的实际行为很容易阅读一目了然.