为什么会有函数调用参数带标签的写法?
ObjC函数参数形式与众不同,实参前会加前缀,尤其参数很多的情况,可读性很强。例如:
[person setAge: 29 setSex:1 setClass: 35]; 这种参数前面加前缀描述也被叫标签(Label). 注意,要把标签和函数签名区分开,函数签名是更大的名词,包含函数名称、参数的组合。当然,也可以对第二个之后的参数不加前缀,形如: [person setAge: 29 :1 : 35];
如果是C++代码,参数很多,有时会记不清参数位置。
C#较新版本同样引入了如上的类似ObjC的函数调用语法增强可读性。
Swift函数调用的参数传递需要加前缀是否是冗余?
事实上,很少有编程语言函数调用传参需要加参数前缀,ObjC和Swift遵循的规则是函数参数易读原则,当一个函数有超过3个参数甚至更多,程序员可能不能直观理解每个参数的意义,甚至参数位置用错,加上前缀的调用方法反而更清晰可靠。
函数调用
函数调用的语法
大部分编程语言,在函数名后面加上括号(以及参数)作为函数调用。
- C/ObjC/C++/Java/C#/Python 等均是如此。
不带括号的函数名
- C/ObjC/C++ 语言单独的函数名并不会调用函数,例如 func; 只会计算函数地址,然后结束,没有调用。
- Python 类似,不带括号的函数名不会执行函数。
函数参数
和普通变量声明类似,函数参数类似于多个普通变量声明。
参数形式
- 大部分编程语言的函数参数放在函数名紧随的圆括号里,不同参数用逗号分隔。
C/ObjC/C++/Java/C#/Kotlin/Python 等均是此。
参数列表和逗号表达式
函数参数列表虽然以逗号分隔,但不是逗号表达式。即,函数参数里面的逗号一定不是逗号运算符,而是函数参数分隔。如果一定需要在函数参数用逗号表达式,用括号括起来。
声明和调用类型不一致
- C语言函数有声明和定义两种形态,在某些情况,可能出现函数声明晚于函数调用,编译器没法知道真实的参数类型,会执行默认的类型转换。
- 例如先调用func(1.2),再定义void func(float f),编译器会认为调用时传入的是double类型变量1.2,但实际执行参数是float,结果不如预期。
- Java/C#/Python不存在这种情况,编译器或解释器提前会获取类型信息而不是延迟到调用时。
一些独特的函数参数形式
- 经典C语言将函数参数单独声明,类似 int f(a, b) float a, b; … 这种写法已被摒弃。
- ObjC函数参数形式与众不同,实参前会加前缀,尤其参数很多的情况,可读性很强。例如:
[person setAge: 29 setSex:1 setClass: 35]; 如果是C++代码,参数很多,有时会记不清参数位置。
当然,也可以对第二个之后的参数不加前缀,形如: [person setAge: 29 :1 : 35]; - C#新版本同样引入了类似ObjC的语法增强可读性。
- Kotlin 支持具名参数,支持形如:形参1 = 实参1 这种形式。
show(name = "Alex", age = 29); - Python 提供的方式和Kotlin类似,被称为关键字实参,例如:
函数原型:def show(name, age)
调用方式:show(age = 29, name = "Alex");
形参和实参
- 形式参数和实际参数不必要同名,C语言可以从汇编代码看到,名字其实是地址或寄存器的代名词,和代码中的名字无任何关系。
- Parameter和Argument都是参数,在很多场景二者没区别。Wiki的说法是parameter表示形参,argument表示实参,这有点学院派了,仁者见仁智者见智。
隐式类型转换
- 实参类型可以隐式转换成形参,编译器才不会报错。
参数默认值
- C/ObjC 不支持默认参数。
- C++/Java/C#/Python/PHP 等均支持函数参数默认值,一般而言,默认值参数必须放在最后。
- Kotlin 默认参数不一定放在最后,它通过具名参数显式指定参数。
若文章对您有帮助,欢迎关注 程序员小迷 。助您在编程路上越走越好!
微风不燥,阳光正好,你就像风一样经过这里,愿你停留的片刻温暖舒心。
我是 程序员小迷 (致力于C、C++、C#、Android、iOS、Java、Kotlin、Objective-C、Swift、Shell、JavaScript、TypeScript、Python等编程技术的技巧经验分享),若作品对您有帮助,请关注、分享、点赞、收藏、在看、喜欢,您的支持是我们为您提供帮助的最大动力。