自动化开发软件[按键精灵] 安卓/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

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

相关推荐
_阿南_14 小时前
Android文件读写和分享总结
android
Avan_菜菜19 小时前
FRP 内网穿透完整实战:从 HTTP 映射到 HTTPS 自签代理
运维·nginx·https
通玄1 天前
Jetpack Compose 入门系列(六):Navigation 3 页面导航
android
rocpp1 天前
Android 多语言切换实战:从 Context 到 Android 13 应用语言适配
android·kotlin
释然小师弟1 天前
Android开发十年:反思与回顾
android·后端·嵌入式
黄林晴1 天前
用了这么久 Koin Scope,原来一直都用错了?
android·kotlin
爱勇宝2 天前
我做了一个只用来搜歌词的小 App
android·前端·后端
SelectDB2 天前
Litefuse 开源并推出单进程轻量模式,25 秒就能跑起来的 Agent 可观测与评估平台
运维·后端·自动化运维
壹方秘境2 天前
我用Go语言开发了一个跨平台的HTTPS抓包和调试工具
前端·后端·ios
众少成多积小致巨2 天前
JNI (Java Native Interface) 技术手册中文参考指南
android·java·c++