对比不同编程语言中的参数默认值和扩展参数(可变参数)

对比不同编程语言中的参数默认值和扩展参数(可变参数)

 

  本文讨论C++、JAVA、C#、EF中参数默认值和扩展参数(可变参数)的实现。只作对比,尽量客观陈述,不作优劣之分,以免引起无谓的语言之争。

  如果错误之处,敬请指正。

 

一、参数默认值

C++:

定义方式:

  int  method1( int  a  =   0 )
 
int  method2( int  a ,  int  b  =   0 int  c  =   0 )

可以为一个或多个参数指定默认值,第一个具有默认值的参数后面的参数都必须有默认值。
如果在头文件(.h)中指定了参数默认值,对应的定义文件(.cpp)中不能重复指定参数默认值(即使默认值是一致的),
许多人采用这种妥协的方法:int method(int a /* = 0 */) { ... }

调用方式:

 x.method1();  // 参数a默认值为0,等效 x.method1(0)
 x.method2( 100 );  // 参数b,c均使用默认值0,等效 x.method2(100, 0, 0)
 x.method2( 100 200 );  // 参数c均使用默认值0,等效 x.method2(100, 200, 0)
 
// x.method2(100, , 300);  // 错误,必须给参数b一个值

有一个限制,如果为后面的默认参数未使用默认值,它前面的所有默认参数都不能使用默认值。
因为这个限制,有些程序员在设计方法参数时会倾向于易用性——将使用默认值概率最大的参数放在最后面,概率较小的靠前站,而在一定程序上忽略了参数的逻辑顺序。

Java:

直到Java5才开始支持参数默认值。语法规则与C++一致。因为Java中没有头文件,也就没有了“不能重复指定参数默认值”的限制。
Java5之前只能用方法重载变相实现,参数较多的话可能引起过度重载。比如要实现:
 int method2(int a , int b = 0, int c = 0)
的效果,要重载以下三个版本:

  int  method2( int  a)
 
int  method2( int  a,  int  b)
 
int  method2( int  a,  int  b,  int  c)

 

C#:

目前可能并不支持参数默认值。

 

EF:

定义方式:

  int  method1( int  a  =   0 )
 
int  method2( int  a  =   0 int  b,  int  c  =   0 )

与C++规定不同,EF中的每一个参数都可以有默认值,不介意其所在位置。

调用方式:

 x.method1();  // 参数a默认值为0,等效 x.method1(0)
 x.method2( 100 200 );  // 参数c均使用默认值0,等效 x.method2(0, 200, 0)
 x.method2(,  200 , );  // 参数a,c均使用默认值0,等效 x.method2(0, 200, 0)
 x.method2(,  200 );  // 同上

没有C++的限制,不管参数顺序,都可使用其默认值。

 

二、扩展参数(可变参数)

C++:

定义方式:

  int  method( int  i, ...)

调用方式:

 x.method( 1 );
 x.method(
1 2 );
 x.method(
1 2 3 );
 x.method(
1 " abc " true );

参数可以任意扩展,不限制类型和个数。
在方法的实现代码中,无法取得扩展参数的个数和类型。一般做法是像printf一样,让用户明确告知;或者事先约定好。

Java:

定义方式:

  int  method( int ... i)

调用方式:

 x.method( 1 );
 x.method(
1 2 );
 x.method(
1 2 3 );

编译器会将调用者提供的所有扩展参数组合成一个数组,方法内部可以通过此数组获取各扩展参数的值。

 

C#:

定义方式:

  int  method( params   int [] i)

调用方式:

 x.method( 1 );
 x.method(
1 2 );
 x.method(
1 2 3 );

编译器会将调用者提供的所有扩展参数组合成一个数组,方法内部可以通过此数组获取各扩展参数的值。

 

EF:

定义方式:

  int  method1(extendable  int  i)
 
int  method2(extendable  int  i, bool b)  // 参数可以“组”为单位进行扩展

调用方式:

 x.method1( 1 );
 x.method1(
1 2 );
 x.method1(
1 2 3 );

 x.method2(
1 true );  // 以“组”为单位进行参数扩展
 x.method2( 1 true 2 false );
 x.method2(
1 true 2 false 3 false );

编译器提供某种机制(下一组扩展参数()),可在方法内部可获取各扩展参数的值。

 

三、总结 

在参数默认值和扩展参数(可变参数)方面,Java、C#、EF 都是在继承 C++ 的基础上并有所发展。


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 35
    评论
评论 35
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值