9.4 纯函数

最后更新于:2022-04-01 06:22:11

如果一个函数的返回结果只取决于参数值,并且没有像修改参数、输出一些值等副作用,那么就可认为此函数是纯函数。 下面这个after函数就是一例。此函数比较两个Time变量并返回一个布尔值并指出第一个操作数是否比第二个晚: ~~~ bool after (Time& time1, Time& time2) { if (time1.hour > time2.hour) return true; if (time1.hour < time2.hour) return false; if (time1.minute > time2.minute) return true; if (time1.minute < time2.minute) return false; if (time1.second > time2.second) return true; return false; } ~~~ 当两个时间相等时,函数返回什么?函数是否有适当的返回值?如果是你为此函数编写文档,你会专门提及这种情况吗? 另外一例是addTime函数,负责计算两个时间值之和。比如现在是9:14:30,你的面包机工作时间是3小时35分钟,你可以使用addTime函数来计算什么时候面包做好。 下面是此函数的一个草稿,不一定完全正确: ~~~ Time addTime (Time& t1, Time& t2) { Time sum; sum.hour = t1.hour + t2.hour; sum.minute = t1.minute + t2.minute; sum.second = t1.second + t2.second; return sum; } ~~~ 下面举一个使用该函数的例子。若currentTime为当前时间,breadTime为面包机做面包用的总时间,你就可以用addTime计算面包做好的时间了。 ~~~ Time currentTime = { 9, 14, 30.0 }; Time breadTime = { 3, 35, 0.0 }; Time doneTime = addTime (currentTime, breadTime); printTime (doneTime); ~~~ 这段程序的输出为12:49:30,答案正确。另外,还有些例子的结果是不正确的。你能想出一个吗? 这个函数的问题在于它没有处理秒数或分钟数加起来超过60的情况。这种情况我们必须将多出的秒数“进位”到分钟,或者多出的分钟进位到小时。 下面是再次修改函数后的正确版本: ~~~ Time addTime (Time& t1, Time& t2) { Time sum; sum.hour = t1.hour + t2.hour; sum.minute = t1.minute + t2.minute; sum.second = t1.second + t2.second; if (sum.second >= 60.0) { sum.second -= 60.0; sum.minute += 1; } if (sum.minute >= 60) { sum.minute -= 60; sum.hour += 1; } return sum; } ~~~ 代码正确了,但也变长了。稍后,我将给出另一个解决方案,能大大简短代码。 这段代码给出了我们之前没见过的两个操作符:+=和-=,用于简洁的表示变量的增减。比方说,语句 ~~~ sum.second -= 60.0; ~~~ 和语句 ~~~ sum.second = sum.second - 60; ~~~ 是等价的。
';