为什么Default表现得像这样?

时间:2011-06-14 00:01:10

标签: wolfram-mathematica

可以为函数的参数设置Default值:

Default[f] = 5;

然后使用:

f[a_, b_.] := {a, b}

f[1, 2]
f[1]
   {1, 2}
   {1, 5}

这将创建以下值:

DefaultValues[f]
DownValues[f]
   {HoldPattern[Default[f]] :> 5}
   {HoldPattern[f[a_, b_.]] :> {a, b}}

从这一点可能会认为值5未在f的定义中修复,而是解决了DefaultValues赋值。但是,如果我们直接或使用:

更改DefaultValues
Default[f] = 9;

DefaultValues[f]
   {HoldPattern[Default[f]] :> 9}

再次使用f

f[1]
   {1, 5}

我们发现新值使用。

因此,我的问题是:

  • 为什么f[a_, b_.] := {a, b}使用的默认值不会随DefaultValues而变化?

  • 存储的实际默认值(5)在哪里,因为它未显示在DownValuesDefaultValues中?

3 个答案:

答案 0 :(得分:10)

不是答案,但是:
使用保留原始默认值的行为,直到重新定义函数为止,建议快速解决:

在进行任何其他定义之前,为Default定义全局变量。

In[1]:= Default[f]:=$f
In[2]:= f[a_.]:=a

In[3]:= f[]
Out[3]= $f

In[4]:= $f=5; f[]
Out[5]= 5
In[6]:= $f=6; f[]
Out[7]= 6
In[8]:= $f=.; f[]
Out[9]= $f

这也适用于Optional

In[1]:= g[a_:$g] := a

In[2]:= g[]
Out[2]= $g

In[3]:= $g=1; g[]
Out[4]= 1

答案 1 :(得分:8)

来自documentation

  

在将Default[f]用作_.的参数之前,必须始终定义f的必要值。

设置f后重新定义Default[f] = 9;使用新的默认值。所以我的猜测是它是第一次在内部定义,f已定义,即使DefaultValue@f存储新值也不会改变。

答案 2 :(得分:3)

我发现在本地规则的情况下,此行为归因于specifics of internals of RuleDelayed

比较

In[1]:= Default[f] = 5;
replaceAll[f[1], 
  f[a_, b_.] :> Unevaluated@{a, b}] /. (Default[f] = 9; replaceAll) ->
   ReplaceAll

Default[f] = 5;
Block[{RuleDelayed}, 
 replaceAll[f[1], 
   f[a_, b_.] :> Unevaluated@{a, b}] /. (Default[f] = 9; 
    replaceAll) -> ReplaceAll]

Out[2]= {1, 5}

Out[4]= Unevaluated[{1, 9}]

我们可以看到Block RuleDelayed使本地规则符合人们的预期。