Handling more than two possible return values?

When a function returns a boolean, you can easily

if (task()){
   // it worked!
}else{
   // it failed.
}

      

But when it returns several different values โ€‹โ€‹it gets messy

var status = task();
if (status == 1){
   // hmm
}else if (status == 2){
   // hmmmmm
}else if (status == 3){
   // hmmmmmmmm!
}

      

.. Is there an easier way to handle it?

Edit: In response to the answers recommending switch statements, yes, I am aware of this. I asked for something neater than even that?

+2


source to share


6 answers


Depends on language capabilities, but I would do something like this in JavaScript:



var handle_task_1 = function () {
    // handle task 1
};

var handle_task_2 = function () {
    // handle task 2
};

var tasks = {
    1: handle_task_1,
    2: handle_task_2,

    "default": function() {},
};

tasks[task()]();

// Or, with a default action. But it may be too much for some people :)
(tasks[task()] || tasks["default"])();

      

+2


source


I can't tell you which language you are using (JavaScript?), But I usually write code like this:



var result = task();

switch (result)
{
    case 1:
        handleStatus1();
        break;
    case 2:
        handleStatus2();
        break;
    default:
        handleEverythingElse();
        break;
}

      

+5


source


Most languages โ€‹โ€‹have a switch statement, for example:

switch (task()) {
   case 1: // do stuff
      break;
   case 2: // other stuff
      break;
   /// etc.
   default: // what?!
      Error("Unhandleable status code");
}

      

+1


source


If you have multiple chained if statements, each executing a unique block of code, you can use a simple functor class map. Ideally, launching the application will populate this card and you can simply call actions from an instance of that card

The code will look like this:

Action action = (Action) contextMap.get(task());
action.do();

      

This has the advantage that adding new tasks only requires defining a new class for that task and adding it to the context map at startup.

There are other nice things about this approach too

  • taskA () and taskB () can share the same context map and even some of the same actions, so you have less code duplication.
  • Actions can be tested more easily (usually)
  • Sharing code between activities will be easy without ending up with spaghetti code or complex if (status> 2 && status! = 7) statements

And of course, interfaces, varargs and other syntactic sugars help here.

+1


source


If you are talking about an integer or some other primitive return type, the best approach I know is a switch statement.

switch (status)
{
case 1:
  // hmm
  break;
case 2:
  // hmmm
  break;
}

      

However, if you return an object that defines the behavior by following the invocation method, things get a lot neat.

Let's say you have an ISomething interface and two (or more) objects that implement that interface (ASomething and BSomething). If the return type of the method is ISomething, the code will look like this:

ISomething result = task();
result.DoSomething();

      

0


source


Are you looking for exceptions ?

Then you don't need to clutter your code for the success case, and for different error cases you can use different exceptions as needed.

0


source







All Articles