URLhttps://learnscript.net/zh/programming/data/namespaces-and-scope/
    复制链接转到说明  示例

    命名空间,作用域介绍

    我被代码海扁署名-非商业-禁演绎
    阅读 5:13·字数 1566·发布 

    命名空间

    命名空间是一种标识符的管理方案,这些标识符被用于任何可能的实体,比如,变量,函数,类等。同一标识符在不同的命名空间中,其指向的目标和表示的含义是互不干扰的。

    为何需要命名空间?

    大型项目会用到众多的变量,函数等实体,当他们的含义接近时,采用相同的标识符将是合理的,而命名空间可以消除相同标识符之间的冲突。

    嵌套命名空间

    命名空间可以呈现为一种嵌套或树状结构,一个命名空间可被包含在另一个命名空间中,并具有自己的标识符。

    什么是完全限定名?

    在嵌套命名空间中,完全限定名是指一个标识符从根命名空间开始计算的路径,由于他是完整的,因此只要给出完全限定名,就可以定位到相关的标识符,无论当前所处的命名空间是哪一个。

    什么是嵌套类型?

    如果在某个类型所在的命名空间中定义另一个类型,那么被定义的类型就是嵌套类型。

    在下面的 C# 代码中,枚举FlowerColor是嵌套类型,他被定义在类Flower中。

    namespaces_and_scope.cs
    // 类 Flower,表示一朵花
    class Flower
    {
    	// 嵌套类型 Color
    	enum Color
    	{
    		// 没有颜色
    		None = 0,
    		// 红色
    		Red = 1,
    		// 白色
    		White = 2,
    		// 蓝色
    		Blue = 3,
    	}
    
    // 字段 Color,表示花的颜色,随机产生 private Color color = (Color)new Random().Next(1, 4); // … }

    显式命名空间

    要定义显式命名空间,一般需要使用特定的关键字,并给出命名空间的完全限定名,或相对于当前命名空间的路径,名称。

    在下面的 C# 代码中,我们显式定义了命名空间World.Animals,他包含了类Lion

    namespaces_and_scope.cs
    // 命名空间 World.Animals
    namespace World.Animals
    {
    	// 类 Lion,表示狮子
    	class Lion { }
    }

    隐式命名空间

    隐式命名空间的定义一般由语言自动完成,通常会依据代码文件的名称和路径,或某些实体来生成。常见的一种情况是函数,每个函数都拥有自己的命名空间,因此你可以在函数内定义与函数外变量同名的变量。

    模块,包

    模块和包都具有命名空间的效果,他们可以用于区别功能不同的代码。一般情况下,模块是比包更小的单位,但一些语言可能会做出相反的处理。模块通常会包含变量,函数,类等实体,而包通常是多个模块的集合。在使用模块或包之前,需要进行相应的导入操作。

    下面的 Node.js 模块stat,包含了统计学校总人数的函数getPeopleCount,以及表示学生和教师数量的变量studentCountteacherCount

    school/stat.js
    // 模块 stat
    // 学生的数量
    exports.studentCount
    // 教师的数量
    exports.teacherCount
    
    // 统计学校内的总人数 exports.getPeopleCount = function () { return exports.studentCount + exports.teacherCount }

    在导入模块stat后,我们使用了相关的变量和函数。

    namespaces_and_scope.js
    // 导入模块 stat
    const stat = require('./school/stat')
    
    // 设置学校人数 stat.studentCount = 100 stat.teacherCount = 10
    // 调用模块的 getPeopleCount 函数,获取学校内的总人数 console.log(`学校内的总人数为:${stat.getPeopleCount()}`)
    学校内的总人数为:110

    作用域

    作用域是指标识符的有效作用范围,在该范围内,标识符是可以被识别的。在命名空间系统中,一个标识符的作用域不仅限于其所在的命名空间,还包括包含在该命名空间中的命名空间。在这样的规则下,根命名空间中的标识符具有全局效果,可以被其他命名空间识别,比如,全局变量,全局函数。

    当某个标识符在当前命名空间中不存在时,一般会在树状结构中逐步向根命名空间搜索,直到该标识符在某个命名空间中被找到,或以类似于“未定义”的警告结束。

    下面的 C# 函数sum会进行加法计算,计算结果被保存至函数外的total变量。

    *.cs
    // 变量 total,用于保存计算结果
    int total = 0;
    // 函数 sum,进行加法计算
    void sum(int num)
    {
    	// 函数内可以访问函数外的变量 total
    	total += num;
    }
    
    // 调用 sum sum(7); sum(9); Console.WriteLine($"结果为:{total}");
    结果为:16

    源码

    namespaces_and_scope.cs·codebeatme/programming·GitHub
    school/stat.js·codebeatme/programming·GitHub
    namespaces_and_scope.js·codebeatme/programming·GitHub