Autohotkey变量进阶

作者: 河许人 | 来源:发表于2016-07-02 23:46 被阅读695次

    变量

    • 变量是什么
    • 变量命名规则
    • 变量类型详解
    • 变量的容量和占用内存情况

    变量是什么

    顾名思义,变量就是会变的量,量就是多少的意思,所以再引申一点,变量就是变化多少的代名词。简单了解了变量的概念,下边我就讲一下变量的命名规则。

    变量命名规则

    首先说明一点,autohotkey语言变量命名规则很宽松,变量可以在脚本的任意位置读取或修改它们的内容. 除了在函数页面注明的情况,变量都是不需要声明的;使用它们的时候它们就产生了(每个变量初始为空)。用起来非常方便,但是看起来也会显得比较混乱,下边简单谈一下变量的命名:

    1. 不能与表达式运算符冲突,因为单词 AND , OR 和 NOT 作为表达式的运算符使用, 所以通常不应该把它们用作变量名称. 在表达式中使用这样的名称会无法正确计算.
    2. 不能与函数名冲突,跟函数名冲突后,会给阅读者造成很大困扰,同时也会引发一些运行错误。
    3. 不能与内置变量冲突,冲突后系统会当作内置变量处理。
    4. 不能与环境变量冲突。

    几点提示:

    1. 变量名不区分大小写 (例如, CurrentDate 等同于 currentdate ). 变量名可以含有多达 253 个字符, 并且可以由字母, 数字以及后面的标点组成: # _ @ $
    2. 考虑到命名的惯例, 通常在命名变量时最好仅使用字母, 数字和下划线 (例如: CursorPosition , Total_Items 和 entry_is_valid ). 这样的风格可以让熟悉其他计算机语言的人更容易理解您的脚本. 而且, 如果您在 AutoHotkey 和其他语言中使用相同的风格, 您会发现能更容易重新读懂自己的脚本.
    3. 尽管变量名可以完全由数字组成, 但通常这样的名称仅用于 传入的命令行参数 . 这样数值名称的变量不能用在 表达式 中, 因为它们会被看成是数字而不是变量.

    变量分类

    AutoHotkey 中没有明确的变量类型.我根据经验总结,ahk的变量类型有以下几种分法:

    按照数据类型划分有

    1. 数字型变量
      数字型变量分为两种整型和浮点型,所谓整型就是整数,所谓浮点型就是带小数点的数,举个例子:
    a=18
    b=1.8
    

    a就是整形,b就是浮点型

    1. 文本型变量,字符串
    a=河许人
    
    1. 布尔型变量,true/flase,on/off等
    a=true
    b=off
    

    然而, 只包含数字 (可以含有小数点) 的变量进行数学运算或比较时, 会被自动转换为数值. (为了提高性能, 在内部会对数字进行缓存以避免与字符串之间的转换.)

    按照作用域和生命周期划分

    分为全局变量、局部变量和静态变量,谈到这里就涉及到两个概念:作用域和生命周期。

    这是两个完全不同的概念,虽然很多时候相互关联。作用域是作用在空间上的,比如一个变量在代码的哪些行能访问,哪些行不能访问。而生存期是作用在时间上的,比如一个变量的值在函数返回后是否失效。

    全局变量

    全局变量比较好理解,如果一个变量是全局变量,那么程序中的所有代码都可以访问到这个变量(除非存在同名的局部变量或者静态变量)。全局变量用 global 定义。

    看一个例子。

    a := 1
    global b := 2
    c := 3
    fun()
    {
    ; a 不是全局变量,访问不了,弹出空字符串
        MsgBox, % a
    ; b 是全局变量,弹出 2
        MsgBox, % b
    ; 在函数里也可以将 c 变成全局变量
    global c
    ; 弹出 3
        MsgBox, % c
    }
    

    注意代码里的 a 并不是全局变量,虽然它的作用域要比函数里的局部变量要大,在所有文件的函数外都可以访问,但在函数内它是不能被访问到的,这算是一个特例。

    局部变量

    在函数里使用的变量通常是局部变量。

    fun()
    ; a 并不是全局变量,弹出空字符串
    MsgBox, % a
    ; b 是全局变量,弹出 2
    

    MsgBox, % b
    fun()
    {

    a := 1
    global b := 2
    

    }

    注意这里 b 是在函数里定义的全局变量,但不管是在什么地方定义的,在其他地方都可以访问到。

    静态变量

    全局变量和局部变量的作用域和生存期都不一样。全局变量的作用域和生存期都是全局的,局部变量的作用域是在函数内部,生存期是从函数开始执行到函数返回。

    但还有一种比较特别的变量是静态变量。

    ; 弹出 1 1(第一次)
    

    fun()

    ; 弹出 1 2(第二次)
    fun()
    fun()
    {
    a := 1
    static b := 1
    MsgBox, % a " " b
    a++
    b++
    }

    a 就是普通的局部变量,因为每次执行 a 都会被初始化为 1,所以两次运行 fun 函数时 a 的值都是 1。但 b 是一个静态变量(使用 static 定义)。静态变量的作用域和局部变量一样,只能在函数内访问。但生存期和全局变量一样,也就是说一个静态变量定义后,它的值会一直有效,即使函数已经返回了。所有第二次运行 fun 函数后,b 的值已经是 2 了。

    使用场景

    那么什么分别在什么情况下使用三者呢?

    没有特殊需求的场景,都应该使用局部变量,这也是默认的情况。

    如果一个变量是需要全局有效的,那么使用全局变量。但全局变量会导致代码的耦合度比较高,不方便维护,所以尽量少用。有些看似需要使用全局变量的场景,其实使用函数的参数传递更合理。

    如果某个局部变量需要只初始化一次(一般情况是因为初始化有开销,这是主要的场景),或者需要保留上次运行的结果(这会导致代码容易滋生 bug,并且难于测试,尽量少用),那么需要将这个局部变量修改成静态变量。

    按照形式划分

    可以分为普通变量、内置变量、环境变量,普通变量没什么好解释的了,下面详细讲一讲内置变量和环境变量。

    内置变量

    内置变量就是说这些变量名称已经内置到程序中了, 可以在任何脚本中引用. 除了 Clipboard、ErrorLevel和命令行参数, 其他变量都是只读的; 即它们的内容无法在脚本中直接修改.有哪些内容呢?
    •特殊字符: A_Space, A_Tab
    •脚本属性: 命令行参数, A_WorkingDir, A_ScriptDir, A_ScriptName, (...更多...)
    •日期和时间: A_YYYY, A_MM, A_DD, A_Hour, A_Min, A_Sec, (...更多...)
    •脚本设置: A_IsSuspended, A_BatchLines, A_TitleMatchMode, (...更多...)
    •用户空闲时间: A_TimeIdle, A_TimeIdlePhysical
    •GUI 窗口和菜单栏: A_Gui, A_GuiControl, A_GuiEvent, A_EventInfo
    •热键, 热字串和自定义菜单项: A_ThisHotkey, A_EndChar, A_ThisMenuItem, (...更多...)
    •操作系统和用户信息: A_OSVersion, A_ScreenWidth, A_ScreenHeight, (...更多...)
    •杂项: A_Cursor, A_CaretX, A_CaretY, Clipboard, ClipboardAll, ErrorLevel
    •循环: A_Index, (...更多...)
    关于这些内置变量如何使用,在下一课内置变量专题中会详细讲解。

    环境变量

    环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。 环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将使用到的信息。例如WindowsDOS操作系统中的path环境变量,当要求系统运行一个程序而没有告诉它程序所在的完整路径时,系统除了在当前目录下面寻找此程序外,还应到path中指定的路径去找。用户通过设置环境变量,来更好的运行进程。

    环境变量由操作系统维护. 在命令提示符中输入SET并回车后, 您可以看到环境变量列表.

    脚本中可以使用 EnvSet 创建新的环境变量或改变现有环境变量的内容. 但是, 这样的添加和改变都是私有的; 它们不会被系统的其他部分看到. 一个例外是当脚本使用 Run 或 RunWait 运行程序时 (甚至是另一个脚本): 这样的程序会继承其父脚本的环境变量的副本, 包括私有的那些.

    在 v1.0.43.08+, 推荐在所有新脚本中使用以下方式获取环境变量, 例如 Path:
    EnvGet, OutputVar, Path
    关于环境变量的操作,当前课程涉及较少。我会在环境变量控制那一课进行详细阐述,这里略讲。

    **变量的容量和占用内存

    •每个变量最多可以含有64MB的文本(使用#MaxMem可以突破这个限制).
    •当赋值给变量比当前更长的内容时, 会自动分配额外的系统内存给这个变量.
    •通过赋值为空可以释放大变量占用的内存, 例如 Var := "".
    •脚本可以创建的变量数量没有限制. 程序设计用来支持至少几百万的变量而不会出现明显的性能下降.
    •接受数值输入的命令, 函数和表达式通常可以支持 15 位的浮点数精度. 对于整数, 可以支持 64 位有符号整数, 其范围从 -9223372036854775808 (-0x8000000000000000) 到 9223372036854775807 (0x7FFFFFFFFFFFFFFF). 此范围外的任何整数不受支持, 并可能产生错误的结果. 与之相比, 整数的算数运算结果超出此范围时会产生溢出 (例如 0x7FFFFFFFFFFFFFFF + 1 = -0x8000000000000000).
    **

    相关文章

      网友评论

        本文标题:Autohotkey变量进阶

        本文链接:https://www.haomeiwen.com/subject/yqnqjttx.html