15. 函数深入理解

1 前言

函数非常重要,并且我们在数学中早就接触过函数了。

比如,明明y=2x+5这样简单的函数,为什么数学书上常常会出现下面这样的写法呢?

y=f(x)
f(x)=2x+5

我相信很多人以前其实是根本没有细想过的,甚至觉得这明显就是多此一举。

但待你深入学习数学、乃至其它学科,逐渐你会发现,这样写是有其原因的。

任何领域想要长足的发展,都需要有一定的体系结构,而这些体系结构中会有大量重复、低层次的内容,如果不将其压缩,就会造成后续升级繁琐。

比如,乘法就是对加法的压缩,当你想要计算100*100时,你不会想到用100个100去相加,因为那样太繁琐。

同样的,专业领域一般都有属于自己的专有名词,比如计算机领域就有硬盘内存等,它们的作用同样是压缩信息,这样你就不用每次交流都说出一大堆描述性的词来描述这个东西。

也许例子不太恰当,但想来你应该能理解我的意思。

函数对于编程的意义很大程度上也在于此:压缩低层次、相对固定不变的内容,日后直接通过函数名使用即可。

2 深入理解

虽然不同语言中对于函数的实现方法并不相同,但大体可以将函数分为三个部分:

  1. 参数
  2. 内部执行语句
  3. 返回值

也就是说,只要有了上面这三个部分,其实就可以定义一个函数了,比如C/C++中的函数:

返回值 name(参数){
	执行语句
}

比如rust中的函数:

fn funname(参数)-> 返回值{
	执行语句
}

函数名只是函数的一个标识,是用来寻找这个函数位置的,比如很多语言中都存在匿名函数,就是只使用一次的函数,那就没必要使用函数名,因为它并不是必要的。

更进一步抽象的说,函数其实你也可以理解为一个对象,而函数名,实际上就是这个对象的名称,就和普通的变量没什么区别。

这一点在js代码中就非常常见:

let a=10;
let f=()=>{}

上面这句话就是让f变量等于一个函数,()中存放函数参数,{}中存放执行语句,至于返回值则不需要写,因为js中是在运行时推断的。

上面介绍的都是声明函数,也就是告诉程序我写了这个函数,而想要执行它,基本都是通过下面这种代码形式:

ret=funName(参数);

也就是通过函数名+参数的形式来执行函数,然后将执行的结果交给最前面的变量。

对于函数来说,很多语言还存在函数重载,典型的代表就是C++,它可以允许你用一个函数名定义多个函数。

但事实上,这多个函数依旧是不同的函数,并且函数名也不会相同,因为C++编译器在编译的时候会根据你函数的参数来修改你的函数名。

这也是为什么C++中重载函数的参数个数、类型、顺序不能完全相同的原因。

至于类函数,其实也是一个普通的函数,只不过它指定了第一个参数为this指针,也就是当前变量的实例,且不需要我们填。

比如一个类:

class Test{
	public:
	void fun(int a){}
}

如果能拿到fun函数的地址,那么下面两种写法其实是等价的:

Test t;
t.fun(100);

pfun=&fun; //假设拿到了fun函数的地址
pfun(&t,100);//与上面写法实际上是等价的。

这在rust、go等现代化语言中就可以很好的看出来,它们不再支持类,但允许你使用结构体绑定函数。

3 函数名规则

不同编程语言的函数名命名规则基本都是相同的,只是推荐命名规则不同。

其通用的规则如下:

  • 只能包含特定字符:函数名通常只能由字母(大小写英文字母)、数字和下划线组成。例如,calculate_sumget_user_info 等都是符合规则的函数名。
  • 不能以数字开头:函数名必须以字母或下划线开头,不能以数字开头。像 123function 就是不合法的,而 function123 则是可以的。
  • 不区分大小写:大多数编程语言对函数名的大小写是不敏感的。也就是说,myFunctionmyfunction 会被视为同一个函数,这取决于语言规范,但无论什么语言一般都不推荐用大小写来区分函数的作用。
  • 具有描述性:函数名应该能够清晰地表达该函数的功能。例如,一个用于计算两个数之和的函数可以命名为 add_numbers,这样其他人在阅读代码时就能很容易理解函数的用途。
  • 避免使用保留字:不能使用编程语言中的保留字(如 ifelsefor 等)作为函数名,因为这些保留字在语言中有特定的语法含义。

具体到各个语言内时,虽然上面的规则都是通用的,但也存在一些习惯性的写法:

  • Python:推荐使用小写字母,多个单词之间用下划线分隔,这种命名方式被称为蛇形命名法(snake_case),如 calculate_average
  • Java:遵循驼峰命名法(camelCase),即第一个单词首字母小写,后续单词首字母大写,例如 calculateSum
  • JavaScript:和 Java 类似,也常用驼峰命名法,如 getUserItem
  • C++:既可以使用蛇形命名法,也可以使用驼峰命名法,不过在一些大型项目中会有统一的代码风格规范要求。
  • Rust:推荐蛇形命名法

但这也仅仅只是推荐,如果你习惯了某个写法,无论什么语言都可以继续使用,这并不会被视作错误,最多只是警告,比如rust使用驼峰式命名、编译器就会警告。

作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux