【发布时间】:2012-08-08 19:57:47
【问题描述】:
据我所知,不纯函数是指那些在使用相同参数调用时并不总是返回相同值的函数(我一定是遗漏了什么,或者可能是错误的,如果我错了,请纠正我)。
那么为什么printf() 被认为是一个不纯函数呢?
【问题讨论】:
标签: c printf purely-functional
据我所知,不纯函数是指那些在使用相同参数调用时并不总是返回相同值的函数(我一定是遗漏了什么,或者可能是错误的,如果我错了,请纠正我)。
那么为什么printf() 被认为是一个不纯函数呢?
【问题讨论】:
标签: c printf purely-functional
“纯”函数也没有副作用。
换句话说,无论你调用多少次,一个纯函数只会影响任何东西,除了它的输出。
例如,foo 是不纯的,即使它返回零:
int x;
int foo() { x++; return 0; }
int bar() { return x; }
如果foo 是纯的,调用它不会影响bar() 的结果。
printf 不纯,因为它的结果有“副作用”——具体来说,它会在屏幕上(或文件等)打印一些东西。
如果它是纯的,那么你可以调用它十亿次,并确保不会发生任何不好的事情。
但是,如果您真的调用printf 一百万次,那么对于用户来说肯定是不同的- 它填满了他的屏幕(或磁盘空间,或其他)。很明显它不是纯的。
此外:如果您的输出被重定向为您自己的输入(有点没用,但仍然如此),那么调用printf 会影响您从getchar 收到的内容。 :) 所以它也可以直接观察到。
【讨论】:
printf 无关。它也没有解决 WHY printf 不纯(外部 - 相对于内部 - 副作用)。
bar 返回 x
成为纯函数有两个部分。首先,正如您所说,该函数必须始终为相同的输入参数返回相同的值。 printf 不满足的第二个标准是函数不能有 I/O 或对象突变等副作用。
【讨论】:
printf 甚至不满足第一个条件:它返回成功打印的多个字符。
PrintStream.printf 的返回值是 this。
简单地说,printf 是不纯的,因为它确实是 I/O。 I/O 根据定义是不纯的,因为存在 I/O 设备的外部状态(状态可能因执行而异)。
【讨论】:
printf() 不纯,因为它会导致输出到 I/O 设备作为副作用.....
【讨论】:
纯函数在编程中的意义在于,如果它已经有了以相同参数调用该函数的结果,则该实现可以优化该纯函数的调用。显然,调用 printf 无法做到这一点。
附:即使按照您的定义,printf 也是不纯的,因为它可以在成功时返回一个值,而在出现 I/O 错误(例如,输出设备上的空间不足)时返回另一个值。
【讨论】:
很多答案都说明printf 有I/O 作为副作用,但printf 也可能有其他副作用。例如,%n 说明符允许 printf 写入到指定地址(并且是一些安全漏洞的原因)。
【讨论】: