我刚刚在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);
}
}
这一次我假设一个函数实际上返回了一些东西,它应该被设置为某个变量,否则返回的值会去哪里?!
答案 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的情况下,依赖于实现。通常,函数的结果将放在机器寄存器中而不是堆栈中。然后由调用者决定是否使用它。