TSL语言基础 > TSL语言基础 > 函数定义体和函数 > 形式参数与实际参数

不定个数参数...    

简述
函数定义时支持最末尾以...支撑不定个数参数,并支持函数调用。
对于不定个数参数可以使用PARAMS来访问
可以在##函数指针、CALL调用中直接使用...进行传参,也可以在INVOKE等方式中使用调用类的方法等
  • 定义:FunctionName([a,[b,[c......]]]...);
    其中,a,b,c,表示已定义的参数,...表示不定个数的参数,不限个数,在调用时进行定义。
    即支持定义如:FuncA(a,b,...)、FuncA(...)等。
    支持将未定义参数的函数作为不定参数个数的函数。即定义FuncA()等同于定义FuncA(...)
    调用时,根据输入的参数个数,按参数位置进行优先识别已定义的参数,多出来的则按顺序依次识别为不定个数参数。

    不定个数参数组的传递:
    在不定个数参数定义的函数中进行调用时,不定个数参数组可通过...在函数调用之间进行传递

    该功能在新一代TSL语言中支持。

    在不定个数参数的函数实现中:
    1、可通过params获得调用时所有输入参数的值,若通过params[i]进行访问时,下标i从1开始,当输入参数少于定义参数个数时,未输入的参数值为nil,不定个数参数在调用时确定。
    2、可通过ParamCount返回定义的参数个数,逻辑同params。
    3、可通过RealParamCount获得实际输入参数的个数,当输入参数少于定义参数个数时,返回的是实际输入参数的个数。
    如,封装不定参数个数函数FuncB(a,b,c,...),如下:
    Function FuncB(a,b,c,...);
    begin
      echo "所有参数值:",tostn(Params);
      echo "定义的参数个数:",ParamCount;
      echo "实际的参数个数:",RealParamCount;
      return ;
    end;

    执行调用少于定义个数参数时:
    FuncB(1);

    打印结果如下:ParamCount>RealParamCount,Params获取到的未被输入的参数值为nil
    所有参数值:
    array(1,NIL,NIL)
    定义的参数个数:3
    实际的参数个数:1

    执行调用多于定义个数参数时:
    FuncB(1,2,3,4,5);

    打印结果如下:ParamCount=RealParamCount,Params获取到所有参数值
    所有参数值:
    array(1,2,3,4,5)
    定义的参数个数:5
    实际的参数个数:5

  • 范例

    范例01:实现doSum(a,b,c,…)多个数据求和的功能
    //封装函数
    Function doSum(a,...); //…指定不定参数
    begin
      s:=0;
      for i,v in params do
       s+=v;
      return s;
    end;
    //调用
    return doSum(1,2,3,4);

    返回:10

    范例02:通过不定个数参数给子函数传参
    //封装函数:
    Function AAA(a,b,c,d);//展示各参数的值
    begin
      return (b+c+d)/a;
    end;
    Function BBB(a,b,...);
    begin
      c:=a+b;
      return AAA(c,...);
    end;
    //调用
    return BBB(1,2,3,4,5);

    返回:4
    解析:函数中参数的传递按顺序解读,上面示例中即为(3+4+5)/(1+2)最终结果为4。

    范例03:不定个数参数在执行不定函数中的应用+ call方式
    //封装函数实现统一接口执行含有不同参数的函数
    Function doFunc(fc,...); //fc:为函数名或函数指针
    begin
      return call(fc,...);
    end;
    //调用如下:
     return doFunc("StockName",'SZ000002');//返回:” 万 科A”
     return doFunc("FormatFloatExt",101.4567,3);//返回:“101.457”
    //或用下面这种调用方式,效果一样:
    return doFunc(thisfunction(stockname), 'SZ000002');


    范例04:…支持在##方式中调用
    注:与范例03的区别在于,##调用必须是函数指针,而非函数名字符串,可通过thisfunction(functioname)方式获取。
    //封装函数doFunc2,通过函数指针方式调用函数
    Function doFunc2(fc,...); //fc:为函数指针
    begin
      return ##fc(...);
    end;
    //调用
    return doFunc2(thisfunction(stockname),'SZ000002'); //返回:” 万 科A”


    范例05:不定个数参数在类中方法的应用示例
    //封装类testC
    type testC=class()
    public
      function fcA(a,b,c);
      begin
       return a+b+c;
      end;
      function fcB(a,b,c);
      begin
       return a$b$c;
      end;
      function gg(f,...);
      begin
        if f="Int" then
         r:=fcA(...);
        else r:=fcB(...);
        return r;
      end;
    end;
    //调用:
    obj:=new testC();
    echo obj.gg("Int",2,20,200);
    echo obj.gg("Str",2,20,200);

    打印结果为:
    222
    220200
    拓展:不定个数参数…在invoke中的使用示例,在上面示例的基础上,再封装模型设用该类的任意方法,如实现如下:
    Function doTestCFuc(fcName,...);
    begin
      obj:=new testC();
      return invoke(obj,fcName,0,...);
      //return Invokeinarray(obj,fcName,0,...);
    end;
    //调用:
    return doTestCFuc('gg',"Int",2,20,200);

    返回结果为:222