参数的个数
没有入参,没有返回值
此时,函数不能跟其他代码块进行交互,退化成了一个指令。
void sayHello()
{
printf("do something\n");
}
若干个入参,没有返回值
数据的消费者。
void saveLog(char* msg)
{
FILE *file = fopen("log.txt", "w");
fwrite(msg, sizeof(msg), 1, file);
fclose(file);
}
没有入参,有返回值
数据的提供者。效果上相当于一个变量。
function getConfig()
{
return [1, 2, 3];
}
多个参数
将参数平铺展开传入,是一个比较直观的方式。但是参数过多时,代码的可读性下降,扩展性下降。这个时候将参数打包成一个对象传参。大量参数传递时,一般分为两部分,控制参数和业务参数。参数个数太多时,参数的装箱和拆箱也是很麻烦的一件事情。
function queryUserInfo($uid, $userName, $mobile, $nickname, $birthday, $pageSize, $pageNum)
{
return [];
}
$param = [
// 分页控制参数
'page_size' => $pageSize,
'page_num' => $pageNum,
// 业务查询参数
'uid' => $uid,
'user_name' => $userName,
'nickname' => $nickname,
'birthday' => $birthday
];
function queryUserInfo($param)
{
}
可变长度参数
将多个参数打包,虽然提升了扩展性,但是使用不太方便,容易导致代码的膨胀。可变参数提供了一个折中的方案。
printf("%s", 'hello world');
printf("%s %s", 'hello', 'world');
传递大量的参数的函数,往往是一个大而全的混杂函数。我们可以把它拆分为一个系列函数。
function queryUserInfoByMobile($mobile)
{
}
function queryUserInfoByUserName($userName)
{
}
// ....
入参的值问题
对于一些控制参数,其取值范围可能较小,而且变动也不大。这个时候,可以使用参数默认值,以减少一些模板代码。
function queryUserInfoByMobile($mobile, $pageNum, $pageSize)
{
}
$mobile = '134xxx';
$pageNum = 1;
$pageSize = 10;
queryUserInfoByMobile($mobile, $pageNum, $pageSize);
function queryUserInfoByMobile($mobile, $pageNum, $pageSize=10)
{
}
$mobile = '134xxx';
$pageNum = 1;
queryUserInfoByMobile($mobile, $pageNum);
控制参数的值,往往是要定义成枚举值的。如果一些参数的值范围较大,枚举值的数量比较多。如果我们使用位的组合来产生更广泛的值域,这样可以减少冗余的代码。
$data = [];
json_encode($data, JSON_UNESCAPED_SLASHES);
json_encode($data, JSON_UNESCAPED_UNICODE);
json_encode($data, JSON_UNESCAPED_SLASHES|JSON_UNESCAPED_UNICODE);
数据的隔离
以上讨论的函数,是不依赖于上下文执行的纯函数。这些函数可以重复执行。代加工的数据只从入参获取,加工后的数据只通过返回值传递。
而函数可以通过其他的方式获取数据,从而打破了函数对数据的隔离。比如,通过参数引用、通过进程间通信、通过函数闭包、通过全局变量获取数据、通过网络获取数据、通过系统调用获取数据等。