跳到主要内容
版本:master

include

1. 概述

本文档介绍GS语言中的include机制,这是一种在编译阶段直接将文件内容插入到当前文件的预处理指令。include与C/C++中的#include指令功能相似,适用于代码片段的重用和头文件包含。

本文面向GS初学者或需要回顾GS#include机制的同学。

通过阅读本章节,您将掌握include的基本用法和路径规则,理解include与import的本质区别,学会在适合的场景下选择正确的代码包含方式。

2. include 基础

2.1 include声明

#include是一种在编译阶段将文件内容直接插入到相应文件中的预处理指令,其基本语法如下:

#incldue "include_path"

需要注意的是#include机制仅支持字符串字面量作为include_path路径,而不支持以.分割的路径名形式。同时#include 机制直接在预编译阶段将#include语句替换为相应路径文件内容。其导入的函数或变量符号等如同在本文件定义的函数或变量一样,可以直接进行调用。

实际上#include的作用和c++中的#include完全相同,示例如下:

// bar.gs
public string bar()
{
return "World";
}

string bar1()
{
return "World";
}

private string bar2()
{
return "World";
}

protected string bar3()
{
return "World";
}
// foo.gs
#include "bar.gs"

public string foo()
{
return "Hello ";
}

write(foo(), bar(), "\n"); // collect
write(foo(), bar1(), "\n"); // collect
write(foo(), bar2(), "\n"); // collect
write(foo(), bar3(), "\n"); // collect

示例2-1:include 使用示例

示例的输出结果如下:

Hello World
Hello World
Hello World
Hello World

从示例可以看出,#include语句将bar.gs脚本中的函数函数public string bar()string bar1()private string bar2()protected string bar3()均导入到了foo.gs脚本中,无论函数被定义为private还是protected在调用函数时均可以如同定义在同一文件中的函数一样直接调用。

实际上此时的foo.gs脚本等效于:

// foo.gs
public string bar()
{
return "World";
}

string bar1()
{
return "World";
}

private string bar2()
{
return "World";
}

protected string bar3()
{
return "World";
}

public string foo()
{
return "Hello ";
}

write(foo(), bar(), "\n"); // collect
write(foo(), bar1(), "\n"); // collect
write(foo(), bar2(), "\n"); // collect
write(foo(), bar3(), "\n"); // collect

示例2-2:include 使用等效示例

提示

​ 一般情况下需要被#include包含的文件后缀会被更改为.gsh以与脚本文件进行区分。

2.2 include 使用场景

这里举例说明一些#include包含的常用场景:

  • 常量或通用宏的定义

    • pkgs/lua53中通过#define宏定义封装了一系列的常量

    • /* thread status */
      #define LUA_OK 0
      #define LUA_YIELD 1
      #define LUA_ERRRUN 2
      #define LUA_ERRSYNTAX 3
      #define LUA_ERRMEM 4
      #define LUA_ERRGCMM 5
      #define LUA_ERRERR 6

      /*
      ** Event codes
      */
      #define LUA_HOOKCALL 0
      #define LUA_HOOKRET 1
      #define LUA_HOOKLINE 2
      #define LUA_HOOKCOUNT 3
      #define LUA_HOOKTAILRET 4

      /*
      ** Event masks
      */
      #define LUA_MASKCALL (1 << LUA_HOOKCALL)
      #define LUA_MASKRET (1 << LUA_HOOKRET)
      #define LUA_MASKLINE (1 << LUA_HOOKLINE)
      #define LUA_MASKCOUNT (1 << LUA_HOOKCOUNT)
  • 通用工具或指令封装

    • pkgs/lua53中通过#define宏定义封装了一些lua的常用命令

    • /* Macro functions */
      #define lua_pop(L,n) dll.lua_settop(L, -(n)-1)
      #define lua_newtable(L) dll.lua_createtable(L, 0, 0)
      #define lua_register(L,n,f) (lua_pushcfunction(L, (f)), lua_setglobal(L, (n)))
      #define lua_pushcfunction(L,f) dll.lua_pushcclosure(L, (f), 0)
      #define lua_strlen(L,i) dll.lua_rawlen(L, (i))
      #define lua_objlen(L,i) dll.lua_rawlen(L, (i))
      #define lua_isfunction(L,n) (dll.lua_type(L, (n)) == LUA_TFUNCTION)

2.3 include的路径说明

#include的路径支持与import不同,必须以字符串字面量作为包含路径。且#include的包含路径是不能省略末尾的.gs的。以及#include的路径一般是以运行时 driver的根路径开始计算的。路径的一些示例如下:

路径说明
/pkg/cjson/cjson.gs加载/pkg/cjosn/cjson.gs
./bar.gs加载当前文件夹下的bar.gs
../bar.gs加载当前文件夹的父文件夹下的bar.gs

3. 拓展阅读

更多有关#include的详细信息请参照手册文档

4. 总结

本章学习了GS语言中的include机制,理解了它与import的本质区别:include编译阶段的文本替换,而import运行时的模块加载。我们掌握了include的基本语法、路径规则以及适用场景。至此,我们已经全面学习了GS语言中三种代码组织机制:component(组件)、import(模块导入)和include(文件包含)。每种机制各有其适用场景,在实际开发中应根据需求选择合适的代码组织方式。

接下来,我们将继续探索GS语言的其他关键概念如域(domain)、对象(object)、函数指针(function)、协程(coroutine)、类(class_map)等内容。