9.4 纯函数
优质
小牛编辑
135浏览
2023-12-01
如果一个函数的返回结果只取决于参数值,并且没有像修改参数、输出一些值等副作用,那么就可认为此函数是纯函数。
下面这个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;
是等价的。