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 - 这样,所有的丑陋都集中在底层,而且函数的实际行为很容易阅读一目了然.
| 归档时间: |
|
| 查看次数: |
1300 次 |
| 最近记录: |