默认情况下,如果我对两个 Blank
使用相同的名称,Mathematica 会抛出一条警告消息。和 BlankSequence
模式:
f[{x_, ___} | x__] := g[x]
Pattern::patv: Name x used for both fixed and variable length patterns. >> Pattern::patv: Name x used for both fixed and variable length patterns. >>
Yet the function works as I desire:
f[{1, 2, 3}]
f[1, 2, 3]
克[1]
g[1, 2, 3]
因此,使用
Off[Pattern::patv]
是否安全?并继续我请?我知道有多种不同的、更冗长的方法可以完成相同的任务,我不想分析它们各自的优点。我只对这个特定的安全性感兴趣。
最佳答案
您的构造在技术上似乎没问题,但从概念上讲,这是混合变量绑定(bind)和模式匹配。换句话说,这依赖于模式匹配器的某些未记录的行为(这不一定是邪恶的,只是要注意)。更糟糕的是,这相当模糊。如果您确定几个月后您自己在更大的上下文中阅读本文不会有任何问题,并且您只为自己使用编写代码,那么我认为没有问题。顺便说一句,另一种选择(正如其他人已经建议的那样):f[{x_, ___}] := f[x]; f[x__] := g[x]
.此外,包装 Quiet
约SetDelayed
比 On/Off
更容易.
编辑
这是我根据@Mr.Wizard 的要求添加的对该问题的扩展 View 。免责声明是,这些只是推测,它们可能完全或部分错误。
变量绑定(bind)阶段是评估范围构造(例如 Module
, With
, Block
, Function
.由 RuleDelayed
形成的延迟规则也是作用域构造,从某种意义上说,模式变量对名称与其他作用域构造的冲突有一定的保护,而且变量绑定(bind)也在那里发生。变量绑定(bind)是将变量名与某个值关联的过程(通过规则的表达式解构获得)。对于像 Module
这样的范围结构, With
, Block
, Function
,我们可以很好地控制变量绑定(bind),因为我们可以覆盖这些结构的 Hold* 属性,写成 x=y;Function[Evaluate[x],y^2]
.对于规则,变量绑定(bind)发生在模式匹配器内部,并且不是可控的。通常,您不会过多考虑绑定(bind)是如何发生的,要么是因为没有歧义,要么是因为名称冲突解决语义在文档或其他地方有详细说明(例如,对于名称冲突有一个通用规则在嵌套的词法作用域结构中,内部绑定(bind)受到青睐)。
对于手头的情况,您受制于规则的变量绑定(bind)机制,以及它与模式匹配器交互的方式。关于模式的一个事实(不知道是否记录在案) - 匹配器是,当给定带有 Alternatives
的模式构建时,它会尝试从左到右进行匹配。 .从常识来看,我们应该期望变量绑定(bind)发生在匹配之后,因此您的构造很好。然而,这是在挖掘我们无法控制的内部结构。模式匹配器/绑定(bind)机制可能没有其他逻辑上一致的方式来表现,或者可能是其他方式。
正如我所说,这本身并不一定是坏事——如果我们有一个特性的经验证据,我们通常会依赖一些未记录的行为,而这个特性允许我们轻松地做一些不平凡的事情。我对这个结构的主要反对意见是它的晦涩难懂——它比使用两个单独规则的代码更难阅读(无论如何对我来说)。
关于wolfram-mathematica - 关闭 Pattern::patv 是否安全?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8374056/