自动化开发软件[按键精灵] 安卓/iOS脚本,变量作用域细节介绍

在按键精灵脚本开发中,变量是承载数据、实现逻辑的核心载体,而变量作用域则决定了变量"在哪里可用、在哪里失效"。用户是不是经常出现单独测试时,脚本可以正常输出结果,但是放到你的脚本中就输出null了。这其实就是变量作用域出来问题,导致80%的人在脚本调试时频繁踩坑:单独测试某段代码正常运行,整合到完整脚本后就出现变量失效、值错乱,甚至语法报错,却找不到问题根源。

先明确一个基础认知:变量作用域的核心是"访问范围",即变量在哪些代码区域可以被读取、修改。按键精灵的变量作用域分为三类------全局作用域、局部作用域、块级作用域,其中块级作用域的"隐藏规则",以及三种声明命令的使用边界,正是多数开发者的知识盲区。

一、全局作用域(全局变量)

在代码最外层定义的变量,理论上在脚本代码中的任何地方,都可以放访问这个变量。

①、全局变量可以直接访问

复制代码
Dim a = 1
TracePrint a

②、全局变量可以在函数内部访问

复制代码
Dim a = 1
fn()
Function fn()
	TracePrint a
End Function

在按键中,如果使用了多线程,全局变量会失效,只对主线程有效,子线程无法访问。我对这个理解就是多线程相当于多个脚本,变量之间不互通,如果想传递变量内容,就需要引入共享变量。

二、局部作用域(局部变量)

局部变量是在函数内部定义的变量,这个变量只能在函数内部被访问,函数外无法访问。

①、函数内访问

复制代码
fn()
Function fn()
    Dim a = 1
    TracePrint a
End Function

②、函数外无法访问

复制代码
fn()
Function fn()
    Dim a = 1
End Function
TracePrint a

这种写法会有语法报错:错误:第6行:名称 a 没有定义。错误码=2430

③、函数内外都定义相同的变量,函数内只访问局部变量,而全局变量无法访问。

复制代码
Dim a = 2
fn()
Function fn()
    Dim a = 1
    TracePrint a
End Function
//输出结果是 => 1

有朋友会说,如果在函数内定义变量之前就访问这个变量,会不会读取到全局变量呢?

答案是不会,只会显示null。

复制代码
Dim a = 2
fn()
Function fn()
    TracePrint a  //输出结果是 => null
    Dim a = 1
    TracePrint a
End Function

三、块级作用域,易错点 ***

在按键中那些有首尾双标签的命令,它们内部的代码区域都可以叫做块级作用域,比如If、For、Do、while等命令。

复制代码
If true Then 
    Dim a = 1
    TracePrint a //输出结果 => 1
End If
TracePrint a //输出结果 => 1

那么易错点在哪里???

块级作用域只在函数内有效,也可以理解为局部变量才受到块级作用域影响。

复制代码
fn()
Function fn()
    If true Then 
        Dim a = 1
        TracePrint a  //输出结果 => 1
    End If
    TracePrint a  //输出结果 => null
End Function

上面两个例子中,同样的if判断代码,第一个可以在判断外面正常输出,第二个在判断外输出为空null。这也就是为啥同样的代码,单独测试没问题,放到其他脚本中就出错的原因。

那么怎么规避这种问题呢?

假设我就想在判断成立时给变量a赋值1,同时在判断结束后输出变量a的内容。那么就要再分开写,定义变量在判断外,复制变量在判断内。

复制代码
Dim a
a = 1

修改一下之前输出为空的代码:

复制代码
fn()
Function fn()
    Dim a
    If true Then 
        a = 1
        TracePrint a  //输出结果 => 1
    End If
    TracePrint a  //输出结果 => 1
End Function

作者会经常图省事,定义变量和赋值一起写,但是出过几次问题后,会刻意提醒自己,在块级作用域中不要这么写,要把定义变量和变量赋值分开来写。

四、选择全局变量还是局部变量呢

这个一般遵循"最小作用域原则",让变量只在需要它的范围生效。这么做的好处:

①、减少bug

②、提高代码可读性

③、容易维护

④、内存占用会相对少一点

个人习惯是优先使用局部变量,但是很多人写脚本习惯用全局变量,定义完全局变量,整个脚本可以任意访问这个变量,使用起来很方便。

两种方式都没有错,就是个人习惯。

有个问题,局部变量的值我非要在函数外面输出,要怎么办?

这个其实就用到函数的返回值了。

复制代码
Function fn()
    Dim a
    If true Then 
        a = 1
    End If
    TracePrint a  //输出结果 => 1
    fn = a
End Function

TracePrint fn() //输出结果 => 1

这边也感谢作者郭立员的经验分享

相关推荐
JZC_xiaozhong8 小时前
数据不互通、审批慢?企业多系统智能协同与流程自动化解决方案
运维·自动化·流程管理·流程自动化·数据集成与应用集成·流程监控·流程可视化设计
爱学习的小囧8 小时前
ESXi 8.0 原生支持 NVMe 固态硬盘吗?VMD 配置详解教程
linux·运维·服务器·esxi·esxi8.0
坚持就完事了8 小时前
Linux中的变量
linux·运维·服务器
hERS EOUS8 小时前
nginx 代理 redis
运维·redis·nginx
Cat_Rocky8 小时前
利用Packet Tracer网络实验
linux·运维·服务器
zhensherlock8 小时前
Protocol Launcher 系列:Trello 看板管理的协议自动化
前端·javascript·typescript·node.js·自动化·github·js
哑巴湖小水怪9 小时前
Android的架构是四层还是五层
android·架构
嵌入式×边缘AI:打怪升级日志9 小时前
Linux 驱动实战:SR501 人体红外传感器驱动开发与调试全记录
linux·运维·驱动开发
正点原子9 小时前
【正点原子Linux连载】第三章 U-Boot使用 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南
linux·运维·驱动开发
忍冬行者9 小时前
MongoDB 三节点副本集离线部署运维手册
运维·数据库·mongodb