aardio 文档

import 语句

aardio 设计了一套轻便灵活的库、名字空间体系,这使 aardio 程序能更好地支持的模块化编程。

请参考:名字空间

导入库

import 语句将一个外部名字空间导入到当前名字空间。

import 语句只能用于导入库创建的名字空间或类名字空间(定义类时会创建同名的名字空间),不能用于导入单个库内部的成员,不能也不必要用于导入函数对象。例如我们可以用 import 语句导入 fsys 库或 fsys.file 类库,但不能单独导入 fsys.copy 函数。注意 io.file 类对象由 io 内置库提供,不允许也不需要单独导入 io.file 。

import 语句首先会在当前名字空间下查找同名对象是否存在,查找时不会触发名字空间的元方法,如果同名对象已经存在并且不是指向相同的库 - 则会报错。import保证不会在同一线程重复加载相同的库。外部库内的代码在一个线程中仅运行一次。

例如:

import a.b.c //将外部库a.b.c导入当前名字空间

import 语句内使用的库名字空间第一个字符不能为下划线 _
aardio 不建议在库名字空间中使用任何下划线( _.aardio 表示默认库除外 )。如果在 IDE 中右键创建库或改动库名,aardio 将会自动移除下划线。如果你确实要这样做,请在资源管理器中手动改名。

aardio的库有三种:

在发布exe文件时,编译器将会自动分析程序中引用到的库并加入目标程序中。并丢弃未引用的库。

  1. 如果希望引用一个库,但发布EXE时希望排除该库(不添加到目标程序),请使用 global.import() 导入库 - 以告知发布程序你希望引用一个库,但是不希望添加到目标程序。 例如调用 global.import("fsys") 可导入 fsys 库。

  2. 如果应用程序不希望引用某个库,但是发布后的 EXE 可能在将来通过动态加载 aardio 代码引用该库,这时候可以将 import 语句移到注释中 - 告知发布程序你不希望引用某个库,但是希望添加到目标程序中。

  3. 在开发环境中调试运行时,aardio 为了调试与优化的需要可能会加载一些你编写的代码中并没有引用的库,例如标准库 win.ui 默认会加载 win.ui.ctrl 名字空间下的一些基础控件库,而这些库又会引用一些基它的标准库。aardio 为了优化启动速度,只有在发布生成EXE时才会完全排除未引用的库。 你完全可以像其他开发工具一样,每次都先生成 EXE 后再运行,当然这样就会像其他一些语言一样每次都要等很久。

详解 import 导入库的过程

import 导入库时查找顺序为:

  1. 内置库

  2. 公共库

  3. 用户库

在开发时,公共库与用户库都是外部库。
外部库文件的物理路径与名字空间路径保持一致(将物理路径中的斜杠替换为圆点就是名字空间路径)。

我们以下面的 import 语句为例详解导入库的过程:

import time.ole //将外部库 time.ole 导入当前名字空间
  1. 查询库缓存

    已导入的库会直接加载到当前名字空间, 如果库缓存已经有这个库则直接导入,不会重复加载相同的库。 如果库缓存里找不到,就继续下面的查找过程。

  2. 查询内置库

    如果内置库中存在该库,导入库,否则继续下面的过程。

    发布为 EXE 以后所有开发时可以正常引用的外部库都会被编译为内置库,同样拥有最高的加载优先级。

  3. 查询公共库

    如果仍然没有找到库。

    在启动当前进程的 EXE 文件根目录下的 ~\lib 目录下查询公共库文件,从根目录逐渐向下层子目录开始搜索,查找顺序如下(按查找顺序先后排列):

    ~\lib\time.ole.aardio
    ~\lib\time\ole.aardio
    ~\lib\time\ole\_.aardio 
    

    如果找到 aardio 代码文件或编译后的二进制 aardio 文件,加载并运行,并将文件路径作为参数传递给目标文件。

    注意:公共库不但包含标准库,还包含其他放在公共库目录的扩展库,所有公共库遵守相同的加载规则。

  4. 查询用户库

    如果仍然没有找到,按第三步的过程,在应用程序根目录 \lib 下查找用户库, 查找顺序如下(按查找顺序先后排列):

    \lib\time.ole.aardio
    \lib\time\ole.aardio
    \lib\time\ole\_.aardio  
    

    如果找到aardio代码文件或编译后的二进制aardio文件,加载并运行,并将文件路径作为参数传递给目标文件。

    应用程序根目录一般是指当前工程目录的 \lib 目录,或独立启动的 aardio 文件所在目录下的 \lib目录。

    请参考: aardio 应用程序根目录

  5. 查找扩展库

    如果当前是运行在aardio开发环境中,仍然没有找到匹配的库文件,aardio会检查扩展库列表并安装扩展库。

    aardio 安装扩展库只是简单地复制粘贴, 如果要卸载,只要右键跳转到定义,直接删除库文件即可。

  6. 检查库是否加载成功

    最后 aardio 检查目标文件是否成功运行,
    目标文件是否创建了新的名字空间全局名字空间 ..time.ole
    如果导入名字空间成功,则导入当前名字空间( self 名字空间 )。

    在 aardio 中库一定要自行创建与路径相同的名字空间。 如果未创建一致的名字空间,则导入库失败。

import global 语句 #

注意在 aardio 中 import global 是一个完全独立的语句,其作用并不是导入库。

注意:

作用:

import global 的作用是在非全局名字空间允许直接访问全局名字空间成员。

举例,原来我们自定义一个名字空间,需要通过 ..print 访问 global.print 这样的全局名字空间的对象。示例:

namespace myNameSpace{
    ..print("默认访问全局名字空间对象要在前面加 .. 操作符") 
}

这是 aardio 与其他编程语言一个较大的区别,
这看起来有些麻烦,但有较大的好处:

需要密集使用的对象,还可以声明为局部变量,例如:

namespace myNameSpace{

    var print = ..print;

    for(i=1;10;1){
        print(i);
    }
}

如果我们希望在自定义名字空间里可以直接访问全局对象,
只要加上 import global 就可以省略 .. 了。

示例:

namespace myNameSpace {

    import global;

    for(i=1;10;1){

        //使用任何全局对象都不用打点了
        print(i);
    }
}

这样做仍然会优先访问当前名字空间的对象,
只有当前名字空间找不到的名字就会自 global 全局名字空间获取。

import global 会有非常轻微的效率代价,对于普通的应用层代码可以忽略也感觉不出来。
但如果是编写库模块、底层代码、编写需要密集执行的代码、对效率或代码质量要求高,那么不建议使用 import global 。有时候哪怕是非常小的代价,累积起来也是可观的。

原理说明:

import global 会将当前名字空间的 _get 元方法指向 global 全局表,这会导致在当前名字空间中访问不存在的成员时转向访问全局表。

Markdown 格式