代码之家  ›  专栏  ›  技术社区  ›  defmeta

如何触发一个函数一次,而且只触发一次…?

  •  6
  • defmeta  · 技术社区  · 17 年前

    我想知道我这样做是否真的是最好的方式?

    无论如何,这就是我通常只触发一次特定方法的方式:

    private var myStatus:Boolean = false;
    

    然后,在经常被调用的函数中。。。

    if (!myStatus) {
        doMyFunction();
        myStatus = true;
    }
    

    正确的事情 ?

    使现代化 :好的,根据我从您的答案中了解到的,我现在不检查全局布尔变量,而是首先检查XML节点是否存在(在写入磁盘之前,我将图像存储在XML结构中),如果不存在,则使用base64编码的图像数据附加一个新节点。我仍然设置一个布尔标志,以便以后我可以用用户编辑的图像数据重写空白图像,如果需要的话。它工作得很好。谢谢大家的帮助!

    我现在也觉得在某些情况下使用这个特殊的(线程不安全的)系统更舒服。

    7 回复  |  直到 17 年前
        1
  •  7
  •   rojoca    17 年前

    最好将此一次调用依赖关系移动到多次调用函数的逻辑。如果只需要调用函数一次,那么只需调用一次。或者,将不同的参数传递给函数,以指示您正在执行不同的操作。

        2
  •  5
  •   Ned Batchelder    17 年前

    doMyFunction 可以打很多次电话。这是因为可以检查多个线程 myStatus ,请查看它是否为false,然后调用 域函数 . 通过先设置变量,可以稍微改善这种情况:

    if (!myStatus) {
        myStatus = true;
        doMyFunction();
    }
    

    要消除竞争条件,您需要一个锁。

        3
  •  4
  •   Todd Gamblin    17 年前

    在C/C++中,您通常可以保留这样一个事实,即通过使用静态变量(如下所示)只调用一次doMyFunction():

    void doMyFunction() {
         // gets called only once.
         // side effects go here.
    }
    
    void functionThatGetsCalledALot() {
        static bool called = false;
        if (!called) {
            doMyFunction();
            called = true;
        }
        // do more stuff
    }
    

    这避免了使用全局变量,但具有相同的效果,并且静态var在相关的地方被声明,因此很清楚发生了什么。请注意,这不是线程安全的,因此如果有线程,则需要一个锁。

        4
  •  2
  •   Steve Jessop    17 年前

    它不是线程安全的。这对您来说可能无关紧要,但您确实说过“语言不可知”:您可能不想在Java的通用库中使用此模式。

    这是一个很难用语言不可知论的方式回答的问题,因为可用的替代方案在很大程度上取决于语言。例如,在POSIX上,如果您需要线程安全性,就有一次pthread_。在C语言中,有静态的局部变量来将布尔值从全局范围中去掉。在任何OO语言中,如果要拍摄“某物”的快照以供以后使用,那么可能会有一个与“某物”(或快照)对应的合适对象,该对象可以存储标志。

        5
  •  0
  •   JoshBerke    17 年前

        6
  •  0
  •   Vilx-    17 年前

    我看没有别的办法了。关于如何提高这一点,我想到的唯一一件事就是线程安全性。但是,只有当您有多个线程调用该函数时,才需要这样做。

        7
  •  0
  •   Brad Gilbert    17 年前

    在Perl 5.10或更高版本中,您将使用 state

    use 5.010;
    
    sub test{
      state $once = 1;
    
      if( $once ){
        $once = undef;
        say 'first';
      } else {
        say 'not first';
      }
    }
    
    test for 1..5;
    

    输出

    first
    not first
    not first
    not first
    not first
    
    推荐文章