据我所知,不纯的函数是那些在用相同参数调用时并不总是返回相同的值的函数(我必须缺少某些东西,或者可能是错误的,如果我是这样的话,请纠正我)。为什么printf()是一个不纯的函数?
那么,为什么printf()
认为不纯的功能?
据我所知,不纯的函数是那些在用相同参数调用时并不总是返回相同的值的函数(我必须缺少某些东西,或者可能是错误的,如果我是这样的话,请纠正我)。为什么printf()是一个不纯的函数?
那么,为什么printf()
认为不纯的功能?
不,“不纯”功能是副作用的功能。
换句话说,不管你有多少次调用它,纯函数会影响什么除了其输出。
例如,foo
不纯,即使它返回零:
int x;
int foo() { x++; return 0; }
int bar() { return x; }
如果foo
是纯粹的,称这是不会影响bar()
结果。
printf
是不纯的,因为它的结果有“副作用” - 具体而言,它打印屏幕上的内容(或文件,等等)。
如果它是纯的,那么你可以称它为十亿次,并确保没有什么不好的事情发生。
但是,如果你真的叫printf
一万次,有一定是用户的不同 - 它填补了他的屏幕(或磁盘空间,或其他)。很显然这不是纯粹的。此外:如果您的输出被重定向为您自己的输入(有点没用,但仍然),那么调用printf
会影响您从getchar
收到的内容。 :)所以它也可以直接观察到。
作为一个纯函数有两个部分。首先,如您所述,该函数必须始终为相同的输入参数返回相同的值。第二个标准,printf
不能实现,是该函数不能有像I/O或对象变异这样的副作用。
'printf'甚至不符合第一个标准:它会成功**返回一些字符**。 – Vladimir 2012-08-12 07:12:20
@Vladimir:每当你给出相同的输入参数时,它总会返回相同的值(这是成功打印的字符数**)。那么它是如何不满足第一个标准的呢? – cirronimbo 2012-08-12 08:32:52
返回的值可能会有所不同,具体取决于a)执行printf和b)写入期间发生的错误。想象一下,如果标准输出已关闭。这里是一个例子:http://pastebin.com/HAtCm2Jh – Vladimir 2012-08-12 08:57:39
简而言之,printf
是不纯的,因为它确实I/O
。根据定义,I/O
是不纯的,因为存在设备的外部状态(状态可能随着执行而不同)。
printf()
是不纯的,因为它会导致输出到I/O设备作为副作用.....
的纯函数编程的意义在于,实现可以优化出一个纯函数的呼叫如果它已经具有使用相同参数调用该函数的结果。很明显,对于printf调用是无法完成的。
P.S.即使通过您的定义,printf也是不纯的,因为它可以在成功时返回一个值,并且在出现I/O错误(例如输出设备上的空间不足)时返回不同的值。
很多答案都解释说printf
有I/O作为副作用,但printf
也可能有其他副作用。例如,%n
说明符允许printf
至将写入指定地址(并且是导致某些安全漏洞的原因)。
虽然正确,但这个答案与'printf'无关。它也不涉及**为什么**'printf'不纯(外部 - 与内部 - 副作用相对)。 – 2012-08-12 05:20:30
是否所有的功能都是不纯的。他们有时间去执行(哲学)! 顺便说一句 - 'bar'返回x – 2012-08-12 05:21:07
@DavidTitarenco:你说得对,我只是补充一点,谢谢! – Mehrdad 2012-08-12 05:23:08