【问题标题】:Default value for function argument, guaranteed to be unique函数参数的默认值,保证唯一
【发布时间】:2013-06-04 16:48:56
【问题描述】:

只是想知道,我是否可以为 ActionScript 3 中的函数提供默认参数,而用户永远无法将其传递给函数。是这样的:

public function getAttr (obj:Object, key:String, def:* = DEFAULT_VALUE):* {
    if (!obj.hasOwnProperty(key)) {
        if (def === DEFAULT_VALUE) {
            throw ReferenceError('Attribute not found: ' + key);
        } else {
            return def;
        }
    } else {
        return obj[key];
    }
}

我不能在这里使用 null、undefined、Number、Boolean 或 String 中的任何一个作为 DEFAULT_VALUE,因为从逻辑上讲,用户可以使用这些值中的任何一个。我需要一些真正独特的东西。例如,在 python 中,我可以这样做:

_DEFAULT_VALUE = object()
def get_attr(obj, key, d=_DEFAULT_VALUE):
    if not hasattr(obj, key):
        if d is DEFAULT_VALUE:
            raise KeyError('Attribute not found: {}'.format(key))
        else:
            return d
    else:
        return obj[d]

但在 ActionScript 3 中,这种方法会产生错误:

Error code: 1047: Parameter initializer unknown or is not a compile-time constant.

也许这里有一些黑客攻击?

【问题讨论】:

    标签: actionscript-3 flash


    【解决方案1】:

    您的问题是 def 值必须是编译时常量,因此无法将默认值存储到 var 中并将其作为默认值传递。 但是这里你真正想要的是知道用户是否在functiondef字段中传递了一个额外的参数,所以你可以检查arguments数组长度,看看是否传递了2个或3个参数。

    public function getAttr (obj:Object, key:String, def:* = null):* {
        if (!obj.hasOwnProperty(key)) {
            if (arguments.length==2) { // no default value passed to the function
                throw new ReferenceError('Attribute not found: ' + key);
            } else {
                return def;
            }
        } else {
            return obj[key];
        }
    }
    

    【讨论】:

      【解决方案2】:

      传递null,并检查null。毕竟,null 是一个实际上什么都不是的默认值,如果您需要提供一个有效的参数,请使用null 作为默认值,这样如果提供某些东西,它就不会为空,因此是有效的。

      【讨论】:

      • 除了 Vesper 所说的,如果真的归结为它,你可以制作两个不同版本的函数,用两个不同的函数签名来半实现这个。例如 funcLite() 和 func()……但就像 Vesper 所说的,你不会对你在 AS3 中要求的东西有很大的运气。这是该语言更大的主要缺点和刺激性的一部分。
      • 不,我个人不认为,这个案例是动作脚本有任何刺激性的迹象。动作脚本是编译语言,因此编译时间常数的限制似乎是合法的。但是,是的,一般来说,动作脚本并不完美:)
      【解决方案3】:

      Vesper 的回答似乎对您的情况是正确的。但是,我对单例使用了类似的方法:

      class Singleton
      {
          private var k_CONS_BLOCKER:Object = {};
      
          public Singleton(cons_blocker:Object)
          {
              if(cons_blocker!=k_CONS_BLOCKER)
              {
                  throw new Error("Use static getter to get the object");
              }
          }
      
          public function getObject():Singleton
          {
              return obj;//you can of course create it now or do some other logic... 
          }
      }
      

      我知道答案与问题没有直接关系,但我认为这个想法总体上解决了问题。

      HTH。

      【讨论】:

      • 在这种情况下 cons_blocker 是必需参数,我的情况是我需要检查用户是否提供了可选参数。帕特里克的回答是完美的,但无论如何都要感谢你。 :)
      猜你喜欢
      • 2011-02-20
      • 2011-04-09
      • 2010-11-28
      • 1970-01-01
      • 2019-09-11
      • 2012-08-03
      • 2015-07-08
      • 2011-08-26
      • 1970-01-01
      相关资源
      最近更新 更多