Autohotkey变量进阶

变量

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

变量是什么

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

变量命名规则

首先说明一点,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).
**

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343

推荐阅读更多精彩内容