函数

函数是一组一起执行一个任务的语句组合。

函数定义
函数定义以关键字func开头,有如下的形式:
func function_name( parameter )
{
   body
}

func:关键字func,函数的定义以func开头
function_name:函数名字,函数名字必须唯一,不能与其它函数,变量,和关键字重名。
parameter:参数,定义在这里的参数被称为形参(形式参数),当函数被调用时,调用者向函数传递实际的值被称为实参(实际参数),形参和实参一一 对应。参数是可选的,可以是一个参数,也可以是一组参数,也可以没有参数。
body:函数主体,一组执行任务的语句组合。函数主体里可以通过return语句返回函数的执行结果,也可以什么也不返回。

调用函数
在主函数或者任何其它函数里可以调用已经定义的函数,函数的定义一定要在调用之前。

函数例子:
//定义函数,完成的任务为返回两个数中较大的那个数
func max(num1, num2)
{
   result=0;
 
   if (num1 > num2)
      result = num1;
   else
      result = num2;
 
   return result;
}

main()
{
    ret=max(99,101);//调用函数
    print("the max number is ", ret);//打印结果
}


函数参数
函数被调用时,实参传递值给形参有2种传递方式:
传值:把实参的实际值复制给形参。在这种情况下,实参和形参是互相独立的,修改函数内的形参不会影响原来实参的值。
Silk传递整数,浮点数,字符串,布尔,句柄,空值时,都是以传值的方式传递。
传值例子:
func test_param(str)
{
    str="I'm cat";
    print(str);
}  
main()
{   
    str="I'm dog";
    print(str);
    test_param(str);
    print(str);//str的值没有被改变
}
运行结果:
I'm dog
I'm cat
I'm dog


传引用:复制实参的内存位置的引用给形参。这意味着,实参和形参指向同一个对象,当形参的值发生改变时,同时也改变实参的值。
Silk传递数组,字典,类,都是以传引用的方式传递。数组和字典对象里可能保存大量数据,采用引用传递不用复制大量数据,提高效率。
传引用例子:
func test_param(array)
{
    array[0]=99;
}  
main()
{   
    arr=[1,2];
    print(arr[0]);
    test_param(arr);
    print(arr[0]);//arr数组里的值已经被改变
}
运行结果:
1
99


如果需要在传引用时保持原来的对象值不变,可以在传递之前通过_copy函数复制一个新对象:
func test_param(array)
{
    array[0]=99;
    print(array[0]);
}  
main()
{   
    arr=[1,2];
    print(arr[0]);
    arr2=_copy(arr);
    test_param(arr2);
    print(arr[0]);//由于传递的是新复制的对象arr2,所以原对象arr保持不变
    return;
}
运行结果:
1
99
1


参数的默认值
函数定义时,可以为参数列表中后边的每一个参数指定默认值。当调用函数时,如果实参的值没有传递,则使用这个默认值,如果指定了值,则会忽略默认值。
func test_param(x,y=100)
{
    z=x+y;
    printf("%d+%d=%d\n",x,y,z);
main()
{   
    test_param(1,2);
    test_param(1);
}
运行结果:
1+2=3
1+100=101


函数变量
函数名称可以赋值给变量,其类型为句柄型,可以作为参数传递,在其它函数内作为回调函数使用:
func test(x)
{
    printf("%d\n",x);
func test2(f)
{
    f(200);
main()
{   
    f=test;//函数名赋值给变量f
    print(_type(f));
    f(100);//调用函数,相当于调用了test(100);
    test2(f);//把函数变量作为参数传递
}
运行结果:
HANDLE
100
200