How do you return two values from a single method?

2019-01-19 10:52发布

When your in a situation where you need to return two things in a single method, what is the best approach?

I understand the philosophy that a method should do one thing only, but say you have a method that runs a database select and you need to pull two columns. I'm assuming you only want to traverse through the database result set once, but you want to return two columns worth of data.

The options I have come up with:

  1. Use global variables to hold returns. I personally try and avoid globals where I can.
  2. Pass in two empty variables as parameters then assign the variables inside the method, which now is a void. I don't like the idea of methods that have a side effects.
  3. Return a collection that contains two variables. This can lead to confusing code.
  4. Build a container class to hold the double return. This is more self-documenting then a collection containing other collections, but it seems like it might be confusing to create a class just for the purpose of a return.

22条回答
啃猪蹄的小仙女
2楼-- · 2019-01-19 11:26

Use var/out parameters or pass variables by reference, not by value. In Delphi:

function ReturnTwoValues(out Param1: Integer):Integer;
begin
  Param1 := 10;
  Result := 20;
end;

If you use var instead of out, you can pre-initialize the parameter.

With databases, you could have an out parameter per column and the result of the function would be a boolean indicating if the record is retrieved correctly or not. (Although I would use a single record class to hold the column values.)

查看更多
仙女界的扛把子
3楼-- · 2019-01-19 11:27

Python (like Lisp) also allows you to return any number of values from a function, including (but not limited to) none, one, two

def quadcube (x):
     return x**2, x**3

a, b = quadcube(3)
查看更多
来,给爷笑一个
4楼-- · 2019-01-19 11:29

Personally I try to use languages that allow functions to return something more than a simple integer value.

First, you should distinguish what you want: an arbitrary-length return or fixed-length return.

If you want your method to return an arbitrary number of arguments, you should stick to collection returns. Because the collections--whatever your language is--are specifically tied to fulfill such a task.

But sometimes you just need to return two values. How does returning two values--when you're sure it's always two values--differ from returning one value? No way it differs, I say! And modern languages, including perl, ruby, C++, python, ocaml etc allow function to return tuples, either built-in or as a third-party syntactic sugar (yes, I'm talking about boost::tuple). It looks like that:

tuple<int, int, double> add_multiply_divide(int a, int b) {
  return make_tuple(a+b, a*b, double(a)/double(b));
}

Specifying an "out parameter", in my opinion, is overused due to the limitations of older languages and paradigms learned those days. But there still are many cases when it's usable (if your method needs to modify an object passed as parameter, that object being not the class that contains a method).

The conclusion is that there's no generic answer--each situation has its own solution. But one common thing there is: it's not violation of any paradigm that function returns several items. That's a language limitation later somehow transferred to human mind.

查看更多
放荡不羁爱自由
5楼-- · 2019-01-19 11:31

For the situation you described, pulling two fields from a single table, the appropriate answer is #4 given that two properties (fields) of the same entity (table) will exhibit strong cohesion.

Your concern that "it might be confusing to create a class just for the purpose of a return" is probably not that realistic. If your application is non-trivial you are likely going to need to re-use that class/object elsewhere anyway.

查看更多
祖国的老花朵
6楼-- · 2019-01-19 11:32

If your function has return value(s), it's presumably returning it/them for assignment to either a variable or an implied variable (to perform operations on, for instance.) Anything you can usefully express as a variable (or a testable value) should be fair game, and should dictate what you return.

Your example mentions a row or a set of rows from a SQL query. Then you reasonably should be ready to deal with those as objects or arrays, which suggests an appropriate answer to your question.

查看更多
等我变得足够好
7楼-- · 2019-01-19 11:32

As much as it pains me to do it, I find the most readable way to return multiple values in PHP (which is what I work with, mostly) is using a (multi-dimensional) array, like this:

function doStuff($someThing)
{
    // do stuff
    $status  = 1;
    $message = 'it worked, good job';

    return array('status' => $status, 'message' => $message);
}

Not pretty, but it works and it's not terribly difficult to figure out what's going on.

查看更多
登录 后发表回答