返回与不返回的功能? [英] Return vs. Not Return of functions?

查看:196
本文介绍了返回与不返回的功能?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

返回或不返回,这是功能的问题!或者,这真的很重要吗?





我用来编写如下代码:

  Type3 myFunc(Type1 input1,Type2 input2){} $ b $但最近我的项目学院告诉我,我应该尽可能地尽量避免写这样的函数,并通过将返回的值放入输入参数中提示以下方法。

  void myFunc(Type1 input1,Type2 input2,Type3& amp ; output){} 

他们相信我这样做会更好更快,在第一种方法中返回。




对于我来说,我开始相信第二种方法在某些情况下更好,尤其是我有很多东西要返回或修改。例如:下面的第二行比第一行更好更快,因为避免在返回时复制整个 vecor< int>

  vector< int> addTwoVectors(vector< int> a,vector< int> b){} 
void addTwoVectors(vector< int> a,vector< int> b,vector< int>& result){}:

但是,在其他一些情况下,我无法购买它。例如,

  bool checkInArray(int value,vector< int> arr){} 

肯定会比

 无效checkInArray(int value,vector< int> arr,bool& inOrNot){} 

在这种情况下,我认为直接返回结果的第一种方法在更好的可读性方面更好。






总结,我很困惑(强调C ++):


  • 函数应该返回什么,不应该返回什么(或试图避免)?
  • 是否有任何标准方式或好的建议让我遵循?

  • 在可读性和代码效率方面,我们可以做得更好吗?

  • 编辑
    我知道这一点,在某些情况下,我们必须使用其中之一。例如,如果我需要实现方法链接,我必须使用返回类型函数

    我知道这个问题可能没有一个单一的答案或安全可靠的东西。此外,似乎需要用许多编码语言来做这个决定,比如 C C ++ 等等。或建议是非常赞赏(更好的例子)。

    解决方案

    像往常一样,当有人提出一个事情比其他,你有没有计时?在完全优化的代码中,您计划使用的每种语言和每个编译器中?如果没有这一点,任何基于性能的论点都是没有意义的。



    我会在第一时间回到性能问题,让我解决我认为更重要的问题:当然,通过引用传递函数参数有很好的理由。我现在能想到的主要原因是该参数实际上是输入和输出,即该功能应该对现有数据进行操作。对我来说,这是采用非const引用的函数签名所表示的内容。如果这样的函数忽略了那个对象中已经存在的内容(或者更糟糕的话,显然希望只能得到一个默认构造的函数),那么这个接口会让人感到困惑。

    现在,回到性能。我不能说C#或Java(尽管我相信用Java返回一个对象首先不会导致副本,只是传递引用),而在C中,您没有引用,但可能需要使用传递指针(然后,我同意传入一个指向未初始化内存的指针是可以的)。但在C ++中,编译器长期完成了返回值优化RVO,这基本上意味着在大多数调用中,如 A a = f(b); ,副本构造函数被绕过,并且 f 将直接在正确的位置创建对象。在C ++ 11中,我们甚至得到了移动语义来明确地使用它并在更多地方使用它。



    如果你只是返回一个 A * 改为?只有当你真的渴望手动内存管理的旧时代。至少,返回 std :: shared_ptr std :: unique_ptr< A>

    现在,如果有多个输出,当然会出现更多复杂情况。要做的第一件事是如果你的设计是真实的:每个功能应该有一个单一的责任,通常,这意味着返回一个单一的值。但是,这当然有例外。例如,分区功能将不得不返回两个或更多个容器。在这种情况下,您可能会发现使用非const引用参数代码更容易阅读;或者,您可能会发现返回一个元组是最好的选择。



    我强烈建议您以双向方式编写代码,并在第二天或周末后回来再看看这两个版本。然后,决定什么更容易阅读。最终,这是良好代码的主要标准。对于少数几个可以看到与最终用户工作流程性能差异的地方,这是需要考虑的另一个因素,但只有在非常罕见的情况下,它应该优先于可读代码 - 并且只需稍加努力,就可以通常都可以同时工作。


    Return or not return, it's a question for functions! Or, does it really matter?


    Here goes the story: I used to write code like the following:

    Type3 myFunc(Type1 input1, Type2 input2){}
    

    But recently my project colleges told me that I should try, as mush as possible, to avoid writing function like this, and suggest the following way by putting the returned value in the input parameters.

    void myFunc(Type1 input1, Type2 input2, Type3 &output){}
    

    They convinced me that this is better and faster because of the extra copying step when returning in the first method.


    For me, I start to believe that the second method is better in some situations, especially I have multiple things to return or modify. For example: the second line of following will be better and faster than the first one as avoiding copying the whole vecor<int> when returning.

    vector<int> addTwoVectors(vector<int> a, vector<int> b){}
    void addTwoVectors(vector<int> a, vector<int> b, vector<int> &result){}:
    

    But, in some other situations, I cannot buy it. For example,

    bool checkInArray(int value, vector<int> arr){}
    

    will be definitely better than

    void checkInArray(int value, vector<int> arr, bool &inOrNot){}
    

    In this case, I think the first method by directly return the result is better in terms of better readability.


    In summary, I am confused about (emphasis on C++):

    • What should be returned by functions and what should not (or try to avoid)?
    • Is there any standard way or good suggestions for me to follow?
    • Can we do better in both in readability and in code efficiency?

    Edit: I am aware of that, under some conditions, we have to use one of them. For example, I have to use return-type functions if I need to achieve method chaining. So please focus on the situations where both methods can be applied to achieve the goal.

    I know this question may not have a single answer or sure-thing. Also it seems this decision need to be made in many coding languages, like C, C++, etc. Thus any opinion or suggestion is much appreciated (better with examples).

    解决方案

    As always when someone brings the argument that one thing is faster than the other, did you take timings? In fully optimized code, in every language and every compiler you plan to use? Without that, any argument based on performance is moot.

    I’ll come back to the performance question in a second, just let me address what I think is more important first: There are good reasons to pass function parameters by reference, of course. The primary one I can think of right now is that the parameter is actually input and output, i.e., the function is supposed to operate on the existing data. To me, that is what a function signature taking a non-const reference indicates. If such a function then ignores what is already in that object (or, even worse, clearly expects to only ever get a default-constructed one), that interface is confusing.

    Now, to come back to performance. I cannot speak for C# or Java (though I believe returning an object in Java would not cause a copy in the first place, just passing around a reference), and in C, you do not have references but might need to resort to passing pointers around (and then, I do agree that passing in a pointer to uninitialized memory is ok). But in C++, compilers have for a long time done return value optimization, RVO, which basically just means that in most calls like A a = f(b);, the copy constructor is bypassed and f will create the object directly in the right place. In C++11, we even got move semantics to make this explicit and use it in more places.

    Should you just return an A* instead? Only if you really long for the old days of manual memory management. At the very least, return an std::shared_ptr<A> or an std::unique_ptr<A>.

    Now, with multiple outputs, you get additional complications, of course. The first thing to do is if your design is actually proper: Each function should have a single responsibility, and usually, that means returning a single value as well. But there are of course exceptions to this; e.g., a partitioning function will have to return two or more containers. In that situation, you may find that the code is easier to read with non-const reference arguments; or, you may find that returning a tuple is the way to go.

    I urge you to write your code both ways, and come back the next day or after a weekend and look at the two versions again. Then, decide what is easier to read. In the end, that is the primary criterion for good code. For those few places where you can see a performance difference from an end-user workflow, that is an additional factor to consider, but only in very rare cases should it ever take precedence over readable code – and with a little more effort, you can usually get both to work anyway.

    这篇关于返回与不返回的功能?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆