被忽略时被调用fn的返回值在哪里?

时间:2011-07-30 21:45:10

标签: language-agnostic

我刚刚在Dive into Python中看到了一个代码片段,其中一个函数正在调用另一个函数(实际上返回了None以外的函数),并且调用函数仍然没有将返回的值赋给变量。

我对此感到震惊并很快去尝试:

>>> def foo(): return "hello_world!"
... 
>>> def bar(): foo()    
... 

我意识到python中的每个函数都返回(None或其他)

令我惊讶的是,当我在之前学过的语言中尝试相同的逻辑时,它们似乎表现出类似的行为:

C:

#include<stdio.h>

char* foo(){return "hello_world!";}

int main(void){
  foo();                                                 // works!
  return 0;
}

C++

#include<iostream>
#include<string>
using namespace std;

string foo(){return "hello_world!";}

int main(){
  foo();                                                 // works!
  return 0;
}

Java:

public class Test{

  public static String foo(){return "hello_world!";}

  public static void main(String args[]){
    foo();                                               // works!
    System.exit(0);    
  }  
}

这一次我假设一个函数实际上返回了一些东西,它应该被设置为某个变量,否则返回的值会去哪里?!

3 个答案:

答案 0 :(得分:7)

它消失了。

如果语言和运行时返回的对象需要进行垃圾回收,则只要函数返回,调用该函数的结果就有资格进行收集。

如果语言和运行时返回引用计数或类似保护的对象,在不再需要该对象时强制立即清理,则在函数返回时将进行清理。

否则,对于所有意图和目的,该值都会丢失。没有伤害,应该完全安全。

答案 1 :(得分:4)

  

这一次我假设一个函数实际上返回了一些东西,它应该被设置为某个变量,否则返回的值会去哪里?!

进入比特桶。维基百科文章:http://en.wikipedia.org/wiki/Bit_bucket

一个例子:

std::set<std::string> set_of_strings;
...
set_of_strings.insert (some_string);

这里std::set::insert()返回一个std::pair,一个指向集合中元素的迭代器和一个指示是否添加了元素的bool。在这种情况下,返回的std::pair将会消失。在许多情况下,您只是不关心具有相同值的元素是否已存在。在这种情况下,没有理由检查第二个返回值。在许多情况下,您也不关心迭代器。所以,让它消失。

一些过于迂腐的程序员会像这样打字:

std::set<std::string> set_of_strings;
...
(void) set_of_strings.insert (some_string);

(void)应该告诉编译器忽略返回结果。但是,编译器不需要被告知这样做。如果不使用它,它将忽略返回结果。 (void)假设做的是告诉读者代码有意忽略返回值。

但是,你永远不会这样做:

(void) x = 42.0;
(void) a = b = c = 42;

这两个赋值语句都返回一个值。 (如果没有,你将无法说a = b = c = 42。)这只是众多例子中的一个,表明你一直在不知情的情况下将数据发送到比特桶。

我的建议:请勿使用(void)宣布您故意忽略了返回结果。编译器不需要它,代码的合理读者不需要,它只是使编写它的程序员看起来像一个傲慢的知识所有人,他们很可能比他们认为的要少得多。

答案 2 :(得分:0)

在C的情况下,依赖于实现。通常,函数的结果将放在机器寄存器中而不是堆栈中。然后由调用者决定是否使用它。