如何处理第一次调用时行为略有不同的函数?

发布于 2024-09-25 12:06:06 字数 697 浏览 4 评论 0原文

我有一个函数 somefunction() ,它被调用了很多次,但是第一次调用它时,我希望它的行为有点不同。下面是一个示例:

first_time = true;
somefunction(){
  // bunch of code...
  if (first_time)
  {
    first_time = false;
    // do it this way...
  }
  else
  {
    // do it that way...
  }
  // bunch of code...
}

我想到了 3 种方法:

  • 您可以按照上面的示例进行操作 你在那里有“第一次”的概念 是明确的。通常是“第一次” check 只是一个布尔检查,因此 它非常便宜 - 但仍然,当你 在触发的计时器中执行此操作 每几百毫秒关闭一次, 感觉很黑客。

  • 您复制该函数,只需更改第一次调用时需要更改的几行代码,并在开始时调用一个函数,每隔一次调用另一个函数。特别是如果函数很大,在我看来这看起来真的很难看。

  • 您分解somefunction()并为代码完全相同的地方创建单独的函数。然后,您可以第一次创建包装函数,并且每次都使用这些较小的函数。我认为这种方法是最好的,并且是我在涉及计时器的情况下将使用的方法。

想法?

I have a function somefunction() which is called a lot, but the very first time its called I want it to behave just a bit differently. Here's an example:

first_time = true;
somefunction(){
  // bunch of code...
  if (first_time)
  {
    first_time = false;
    // do it this way...
  }
  else
  {
    // do it that way...
  }
  // bunch of code...
}

3 approaches come to mind:

  • You can do as in the example above
    where you the notion of "first time"
    is explicit. Usually the "first time"
    check is just a boolean check hence
    its very cheap - but still, when you
    are doing this in a timer that fires
    off every few hundred milliseconds,
    it feels hack-ish.

  • You duplicate the function and just change the few lines of code that need to be changed when its called the first time and call one function at the start and the other function every other time. Especially if the function is big this looks really ugly IMO.

  • You break up somefunction() and create separate functions for where the code is exactly the same. You then create wrapper functions for the first time and everytime else that utilize these smaller functions. I think this approach is best and is what I'm going to use in my situation involving a timer.

Thoughts?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

云淡月浅 2024-10-02 12:06:06

太笼统;我认为第一种和第三种方法在适当的情况下是可以的(#2 不是 - 违反了 DRY)。而且,它并没有一次又一次地为我显示;我能想到的最常见的是单例模式。你能举一个具体的例子吗?

Too general; I think the first and the third approach are okay in an appropriate situation (#2 isn't - violates DRY). Also, it does not show time and time again for me; the most common I can think of is the singleton pattern. Can you give a specific example?

帝王念 2024-10-02 12:06:06

在像 C# 这样的语言中,您可以像这样使用委托(函数是公共可调用方法):

public delegate void FunctionSignature();

class FunctionContainer
{
  public FunctionSignature Function;

  public FunctionContainer()
  {
    Function = FirstTimeFunction;
  }

  private void FirstTimeFunction() 
  { 
    ...
    Function = FollowingTimesFunction; 
  }

  private void FollowingTimesFunction()
  {
    ...
  }
}

只是一个想法,如果您愿意,也可以是好奇心,但它可能对您有用:-)

In languages like C# you could use delegates like so (Function is the public callable method):

public delegate void FunctionSignature();

class FunctionContainer
{
  public FunctionSignature Function;

  public FunctionContainer()
  {
    Function = FirstTimeFunction;
  }

  private void FirstTimeFunction() 
  { 
    ...
    Function = FollowingTimesFunction; 
  }

  private void FollowingTimesFunction()
  {
    ...
  }
}

Just an idea, a curiosity if you like, but it may work for you :-)

演出会有结束 2024-10-02 12:06:06

第一种方法似乎很好。第二种方法是维护的噩梦。第三种方法似乎会变得比您的描述所需要的要复杂得多。除非在这些特定点分解函数提供逻辑分组,否则您将只是创建一个可能比两个更混乱的解决方法。

我能想到的另一种方法是使用回调函数来运行支持函数作为第一类对象的语言的“第一次”代码。这是一个 JavaScript 示例。

function makeSpecialFunction = function(runOnlyFirstTime) {
    return function() {
        // code before

        if(runOnlyFirstTime) {
            runOnlyFirstTime();
            runOnlyFirstTime = null;
        }

        // code after
    };
};

我知道这不是一个巨大的改进,但如果唯一让您的 someFunction 无法重用,那么这就是您的解决方案。

现在 someFunction 可以使用不同的初始化代码两次。

var init = function() {
    alert("first:init");
};

var init2 = function() {
    alert("first:init2");
};

var someFunction = makeSpecialFunction(init);
var otherFunction = makeSpecialFunction(init2);

someFunction(); // alerts first:init
someFunction(); // doesn't alert anything

The first approach seems just fine. The second approach is a maintenance nightmare. The third approach seems like it will become far more complicated than it needs to be from your description. Unless breaking up the functions at those specific points provides a logical grouping, you will just be creating a workaround which might be even messier than two.

Another way I can think of is to use a callback function to run the "first time" code for languages that do support functions as first-class objects. Here's an example in JavaScript.

function makeSpecialFunction = function(runOnlyFirstTime) {
    return function() {
        // code before

        if(runOnlyFirstTime) {
            runOnlyFirstTime();
            runOnlyFirstTime = null;
        }

        // code after
    };
};

Not a huge improvement I know, but if the only thing keeping your someFunction from being reusable, then this is your solution.

Now someFunction can be used twice with different initialization codes.

var init = function() {
    alert("first:init");
};

var init2 = function() {
    alert("first:init2");
};

var someFunction = makeSpecialFunction(init);
var otherFunction = makeSpecialFunction(init2);

someFunction(); // alerts first:init
someFunction(); // doesn't alert anything
尤怨 2024-10-02 12:06:06

IMO 中最简单且最可维护的一般方案是选项 1。
我将一个 first 参数传递给默认为 false 的函数:

function(first = false)
  if first
    ... do something special
  else
    ... optionally do something else special (if you want)
  ... do main stuff

我同意其他人的观点,即 #2 本质上是一个坏主意,而 #3 可能有点矫枉过正。

这通常就是函数参数的用途——作用于它们并根据它们改变行为。 first 也可以很容易地成为 lastis_weekdayam_i_feeling_lucky 等。

The easiest and most maintainable general scenario, IMO, is option 1.
I'd pass a first parameter to the function that defaults to false:

function(first = false)
  if first
    ... do something special
  else
    ... optionally do something else special (if you want)
  ... do main stuff

I agree with others' opinions that #2 is inherently a bad idea, and #3 may be overkill.

This is generally what parameters to functions are for-- to act on them and alter behavior based on them. first could just as easily be last, is_weekday, am_i_feeling_lucky, etc.

爱*していゐ 2024-10-02 12:06:06

C 具有静态局部变量,其值在调用之间保持不变。您可以将first_time声明为静态变量。它的值只会在第一次调用时初始化。后续调用将使用之前的值。因此它成为一个标志来指示这是否是第一次调用。

void some_function()
{
    static int first_time = 1;

    if (first_time) {
        // do stuff for first call only
        first_time = 0;
    }

    // do stuff for every call
}

C has static local variables whose values persist from invocation to invocation. You could declare first_time to be a static variable. Its value will be initialized on the first call only. Subsequent calls will be use the previous value. Thus it becomes a flag to indicate whether this is the first invocation or not.

void some_function()
{
    static int first_time = 1;

    if (first_time) {
        // do stuff for first call only
        first_time = 0;
    }

    // do stuff for every call
}
梦途 2024-10-02 12:06:06

在某些情况下,您可能可以使用 Sentinel Value,但相反:即传递用于初始化函数的特殊值。我认为这些情况很少见。

更好的可能是选项 3 的变体:将函数放入其自己的类中,并使初始化步骤不是函数的一部分,而是类构造函数的一部分。还有一些情况没有涵盖 - 例如,初始化需要实际的初始值,但我认为这涵盖了大多数情况,并且是最干净的选择。即使需要该初始值,您也可以将其传递到构造函数中,但是随后您的条件逻辑会移至调用方,这可能是一个坏主意。

In some situations you may be able to use a Sentinel Value, but in reverse: that is, pass a special value in to initialize the function. I think these situations are rare.

Better is probably a variant of your option 3: put the function into its own class, and make the initialization steps not a part of the function, but rather a part of the class constructor. There remain some situations that this doesn't cover - where the actual initial value is needed for initialization, for instance, but I think this covers most cases and is the cleanest option. Even when that initial value is needed, you may be able to pass it into the constructor, however then your conditional logic moves out to the caller, and that's probably a bad idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文