使用字符串而不是符号:是好是坏?

Posted

技术标签:

【中文标题】使用字符串而不是符号:是好是坏?【英文标题】:Using strings instead of symbols: good or evil? 【发布时间】:2011-03-02 12:57:14 【问题描述】:

我发现自己经常处理foo->value,... 形式的功能选项列表(或更一般的替换列表)。当 foo 在 $Context 中已经有值时,这会导致错误。防止这种情况的一种明显方法是使用字符串“foo”而不是符号:"foo"->value,...。这行得通,但似乎激怒了我认识的一些经验丰富的 LISPers,他们责备我将符号和字符串混为一谈,并告诉我使用内置的引用结构。

虽然在不使用字符串的情况下编写避免冲突的代码当然是可能的,但它通常看起来比它的价值更麻烦。另一方面,我没有看到太多"string"->value 类型替换规则的例子。所以你的问题是——这是一种可以接受的使用模式吗?..是否有特别合适的情况?..应该在哪里避免?..

【问题讨论】:

【参考方案1】:

在我看来(免责声明 - 这只是我的意见),最好避免使用字符串作为选项名称,至少对于函数中的“主要”选项。字符串 OTOH 完全可以作为设置(选项的 r.h.s.)。正如您所指出的,这并不是说您不能使用字符串。也许,它们可能更适合子选项,并且它们被许多系统函数以这种方式使用(通常是像NDSolve 这样的“超级函数”,可能在选项中有子选项)。我看到使用字符串的主要问题是它们降低了系统和用户的自省能力。换句话说,发现具有字符串名称的选项比具有符号名称的选项更难 - 对于后者,我可以检查包中符号的名称,并且符号选项名称具有使用消息。 You may also want to automate some things, such as writing a utility that finds all option names in the package etc. It is easier to do when option names are symbols, since they all belong to the same context.还很容易发现某些选项没有使用消息,可以通过编写实用程序函数自动完成。

最后,您可以更好地防止类似选项名称的意外冲突。可能有许多选项序列被传递给您的函数,有时它们可​​能包含同名的选项。如果选项名称是符号,则完整的符号名称将不同。然后,您将得到一个阴影警告,同时得到一个保护 - 只会使用正确的选项(完整)名称。对于字符串,您不会收到任何警告,并且可能最终使用不正确的选项设置,如果具有错误设置的重复字符串选项名称(例如,用于不同的功能)恰好位于列表的第一位。这种情况更有可能发生在大型项目中,但是像这样的错误可能很难捕捉到(这是一个猜测,我从来没有遇到过这种情况)。

至于可能的冲突,如果您遵循一些命名约定,例如选项名称始终以大写字母开头,加上将大部分代码放在包中,并且不要以变量或函数名称开头(对于交互式会话中的函数),用大写字母,那么你会大大减少这种碰撞的机会。此外,您应该Protect 选项名称,当您定义它们时,或在包的末尾。然后,碰撞将被检测为阴影情况。避免阴影,OTOH,是一种普遍的必要性,因此在这方面,选项的情况并不比函数名称等特殊。

【讨论】:

+1 从技术上讲,大写符号是为 Mathematica 内置程序保留的,但这种约定被广泛忽略。原因是人们几乎可以肯定大写符号不会有向下价值。我尽量尊重函数名称的保留,但在选项的情况下,我通常使用大写名称来定义自己的选项。 @WReach:大写名称仅保留给System' 上下文中的符号。其他规则只是约定,而且,仅适用于在交互式会话中创建的符号,而不是在包中。在包中,约定是将导出的函数和选项名称大写。这可以在 WRI 和第三方制作的许多附加包中看到。此外,这是 Roman Maeder 在他的“Programming in Mathematica”中给出的建议,这是一个标准参考,尤其是对于包编写。由于全名不同,碰撞会导致阴影,所以会被警告 +1 "我看到使用字符串的主要问题是它们降低了自省能力" +1 此外,(v9) 自动完成功能不适用于字符串选项名称。

以上是关于使用字符串而不是符号:是好是坏?的主要内容,如果未能解决你的问题,请参考以下文章

使用 testID 自动化移动应用程序是好是坏?

VTune:使用 3 个以上端口的高价值是好是坏

使用 Client_credential oauth 授予是好是坏? [关闭]

具有相同名称属性的输入字段的多个表单?是好是坏?

虚拟成员函数对于现代 CPU 中的局部性是好是坏?

火爆全网的“网红带货”到底是好是坏?