Language agnostic 当被忽略时,被调用的fn的返回值去哪里?

Language agnostic 当被忽略时,被调用的fn的返回值去哪里?,language-agnostic,Language Agnostic,我刚才看到一个代码片段,其中一个函数正在调用另一个函数(实际上返回的不是None),但调用函数仍然没有将返回值赋给变量 我被它吓了一跳,很快就去尝试: >>> def foo(): return "hello_world!" ... >>> def bar(): foo() ... 我实现了python中的每个函数都返回(要么None要么其他) 令我惊讶的是,当我在以前学习的语言中尝试相同的逻辑时,它们似乎表现出类似的行为: C: #includ

我刚才看到一个代码片段,其中一个函数正在调用另一个函数(实际上返回的不是
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;
}
Java:

public class Test{

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

  public static void main(String args[]){
    foo();                                               // works!
    System.exit(0);    
  }  
}
一直以来我都在假设如果一个函数真的返回了一些东西,它应该被设置为某个变量,否则返回的值会去哪里

它消失了

对于返回的对象需要进行垃圾收集的语言和运行时,只要函数返回,调用该函数的结果就可以进行垃圾收集

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


否则,无论出于何种目的,该值都将丢失。不会造成任何伤害,而且应该是完全安全的。

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

一直以来我都在假设如果一个函数真的返回了一些东西,它应该被设置为某个变量,否则返回的值会去哪里

它进入钻头桶。维基百科文章:

例如:

std::set<std::string> set_of_strings;
...
set_of_strings.insert (some_string);
(void)
应该告诉编译器忽略返回结果。但是,编译器不需要被告知这样做。如果不使用,它将忽略返回结果。
(void)
应该做的是告诉代码的读者返回值被故意忽略

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

(void) x = 42.0;
(void) a = b = c = 42;
这两个赋值语句都返回一个值。(如果没有,你就不能说
a=b=c=42
)。这只是许多例子中的一个,说明你一直在不知道的情况下向比特桶发送数据


我的建议是:不要使用
(void)
来宣布您有意忽略返回结果。编译器不需要它,代码的合理读取器也不需要,它只会让编写它的程序员看起来像一个自大的无所不知的人,很可能知道的比他们想象的要少得多。

进入空白,再也看不见了。好吧,你确实应该把返回值存储在某个地方。当然,除非你不需要它。这不应该被标记为语言不可知的吗?@Seth绝对,所以我重新标记了它。(你自己难道没有这个特权吗?@Karl是的,但我不想让retag高兴,直到我学会了这件事的艺术(另外,我不想让每个人都生气,因为我做错了而不得不撤销我的retag)。引擎盖下发生的事情取决于实现——就像所有事情一样。语义是定义良好的。关于泄漏返回值,“它是完全安全的”。忽略它可能不是一个好主意,尤其是在许多返回错误代码的C函数中。事实上,不,在python、perl、bash等脚本语言中没有,etc@JamesPerl有一个神奇的变量
$\uuu
,它保存着这些东西,这样它们就不会永远丢失,但那只是Perl。在Python中,您可以从REPL中使用
,但这是为REPL专门编码的,在脚本中,甚至在REPL中编写的函数之间都不起作用-它存储在REPL上执行语句的最后结果。所以,是的,在一般情况下,它确实消失了。@Karl你是对的,我站出来纠正。我也讨厌默认变量,因为当人们像在perl中一样利用它时,它会导致难以阅读的代码
std::set<std::string> set_of_strings;
...
(void) set_of_strings.insert (some_string);
(void) x = 42.0;
(void) a = b = c = 42;