作用域

作用域是程序中的变量所存在的区域,超过该区域变量就不能被访问。Silk语言有全局变量和局部变量。

全局变量
全局变量在整个程序生命周期内都是有效的,在任何函数内部都能访问全局变量。
全局变量在函数的外部定义,一般定义在顶部,保证所有的函数都能访问到。
在函数(包括类函数)内部使用全局变量需要首先用global关键字声明。
global后面可以跟一个或多个全局变量,用逗号分隔。
main函数里可以直接使用全局变量。

_gIndex=0;//全局变量

func set_index(index)
{
    global _gIndex;//使用前声明这是一个全局变量
    _gIndex=index;//在函数里修改全局变量
}
main()
{
        print(_gIndex);//打印全局变量
        set_index(100);//修改全局变量
        print(_gIndex);//重新打印
}
运行结果:
0
100

如果不用global声明,那么在函数set_index内部,_gIndex就被认为是个局部变量,无法修改全局变量:
_gIndex=0;//全局变量

func set_index(index)
{
   _gIndex=index;//这里_gIndex是函数内部变量,赋值不影响外部的全局变量
}
main()
{
        print(_gIndex);//打印全局变量
        set_index(100);//函数不会修改全局变量
        print(_gIndex);//重新打印
}
运行结果:
0
0

如果只是读取全局变量,而不改变全局变量的值,即不重新赋值(赋值意味着定义新变量),那么global声明可以省略:
_gIndex=0;//全局变量

func test()
{
    //这里只是读取了全局变量的值,而没有对全局变量进行赋值操作,所以可以省略global声明,直接使用
    n=_gIndex+10;
    print(n);
}
main()
{
    test();
}
运行结果:
10
原则上我们在使用全局变量时都要通过global声明,所以不推荐省略。

被包含的模块源文件中定义了全局变量,在包含它的源文件中也能使用:
//file1.si
_g1=0;//在file1.si中定义全局变量

//file2.si
#include "file1.si" //包含file1.si
func test()
{
    print(_g1);//打印在file1.si中的全局变量
}


局部变量
在函数内部声明的变量为局部变量,它们只能被该函数内部的语句使用,局部变量在函数外部是不可见的,函数执行完毕局部变量将被释放。
func test(index)
{
    a=1;//a为函数test内部的局部变量
    b=index;//b为函数test内部的局部变量,index为形参,也是test内的局部变量
}
main()
{
        x=0;//局部变量
        test(100);
}


static关键字
如果要防止在不同源文件中定义的全局变量重名,就要用到static关键字。如果在file1.si中定义了全局变量_g1,并在前面加上了static,就表示
这个全局变量仅在当前源文件可见,在其它源文件中是看不到这个变量的。利用这一特性可以在不同的文件中定义同名变量或同名函数,而不必担心命名冲突。
//file1.si
static _g1=0;//在file1.si中定义static全局变量,只在file1中可见

//file2.si
#include "file1.si" //包含file1.si
func test()
{
    print(_g1);//_g1在file2.si中不可见,无法打印
}

//file3.si
#include "file1.si" //包含file1.si

//在file3.si中定义了和file1.si中同名的全局变量,
//由于file1中的变量已经加了static,所以这里定义的变量不会和file1中的同名变量冲突,它们是相互独立的变量
_g1=1;

main()
{
    print(_g1);//这里打印的是file3中的_g1
}

static关键字也同样适用于函数和类,使得不同源文件中定义同名的函数和类,不会产生冲突。
static func test()
{
    print("test");
}

static class Point(x, y)
{
    self.x=x;
    self.y=y;
}