pbai 发表于 5 天前

PowerBuilder 变量作用域:全局/实例/共享/局部到底差在哪

PowerBuilder 变量作用域:全局/实例/共享/局部到底差在哪

很多从别的语言转到 PowerBuilder 的人,第一次写代码就踩在同一个坑上:在窗口里声明了一个变量,切到另一个窗口想用却"找不到";或者明明改了某个值,刷新界面却没变。根子都在"变量作用域"——PowerBuilder 把变量分成全局(Global)、实例(Instance)、共享(Shared)、局部(Local)四种,它们活在哪、谁能看见、什么时候被销毁,规则和其它语言不太一样。本文只讲清这一件事。

一、四种作用域分别"住"在哪


[*]全局变量(Global):写在独立的 Global Variables 声明区(或 .srs 里的 global variables 段),整个应用任何对象、任何脚本都能直接引用。它跟着应用进程活,应用不关就一直在。
[*]实例变量(Instance):写在某个对象(窗口、用户对象、自定义类 n_*)的 Instance Variables 区。每个对象实例各持一份,窗口打开两个就各有一份,互不影响。
[*]共享变量(Shared):同样写在对象里,但同一个类/窗口的所有实例共享同一份。不管你 open 了这个窗口几次,shared 变量只有一份,所有实例读写的是同一个。
[*]局部变量(Local):写在某个事件/函数脚本内部,用 integer li_x 这种。只在那段脚本执行期间存在,脚本一跑完就销毁。


一句话记忆:全局=全应用一份;实例=每个对象一份;共享=每类对象一份;局部=每次调用一份。

二、最容易翻车的三个误用

1. 局部变量"遮蔽"实例变量

如果你在窗口的 Instance Variables 里写了 string gs_user,又在某个按钮的 clicked 事件里写了 string gs_user,那么事件里的 gs_user 是新建的局部变量,改它不会动到实例那份。结果:你以为改了用户名,其实窗口别处读到的还是旧值。规避:实例变量加统一前缀(很多团队用 iv_),局部变量用 li_/ls_,一眼能区分。

2. 误把"应该共享"的状态写成实例变量

比如你想统计"这个窗口被打开过几次"。如果在 Instance Variables 写 integer ii_count 并在 open 里 ii_count++,那每 open 一个窗口实例,计数都从 0 开始——永远统计不到总数。正确做法是用 Shared Variables:shared integer si_count,所有实例 +1 都落在同一份上。

3. 全局变量满天飞

图省事把所有状态都声明成全局变量,短期内"哪都能用",长期就是噩梦:命名冲突、无法测试、多线程下互相踩。PB 12.5 之后更推荐把状态收敛到 nvo(非可视化对象)的实例变量里,再用全局单例去取,而不是裸写 global。

三、实例参考(动手步骤)

下面用用户对象的最小例子,验证"共享 vs 实例"的差异。


// 在 u_counter 用户对象的 Instance Variables 区:
integer ii_mine
shared integer si_common

// 在 u_counter 的某个函数 of_bump() 里:
ii_mine ++
si_common ++
return "instance=" + string(ii_mine) + ", shared=" + string(si_common)



// 窗口 open 事件:创建两个实例
iu_a = create u_counter
iu_b = create u_counter
// 分别调用
// iu_a.of_bump() -> instance=1, shared=1
// iu_a.of_bump() -> instance=2, shared=2
// iu_b.of_bump() -> instance=1, shared=3   // 注意:iu_b 的 instance 从 1 重新开始,shared 继续累加


关键点:iu_b 的 ii_mine 重新从 1 计,因为它属于另一个实例;而 si_common 是 3,因为两份实例共享同一份 shared。这正是"统计总次数"要用 shared 的原因。

四、实操检查清单


[*]状态只在一个窗口/对象内用时,优先用实例变量,别写全局。
[*]需要"所有实例共享同一份"(计数器、配置开关、连接句柄)时,用 Shared Variables。
[*]实例变量加 iv_ 前缀、局部变量加 li_/ls_,避免局部遮蔽实例导致"改了不生效"。
[*]临时计算、循环变量一律用局部变量,脚本结束即释放,不占对象内存。
[*]能用对象封装的状态,就不要裸写 Global Variables;全局越少,后期越好维护、越好测。
[*]多线程/异步场景(uo_thread)下,避免直接读写共享/全局变量,必要时加简单锁或改为消息传递。


变量作用域不是语法细节,它直接决定了你的状态"到底属于谁、改了谁看得到"。把上面几条规则落到命名习惯上,PB 里绝大多数"莫名其妙不生效"的 bug 都会消失。

woyaodwn 发表于 3 天前

感谢,学习了,好好的复习了一下

tomok 发表于 3 天前

写得挺好!
有代码,有分析
页: [1]
查看完整版本: PowerBuilder 变量作用域:全局/实例/共享/局部到底差在哪

免责声明:
本站所发布的一切破解补丁、注册机和注册信息及软件的解密分析文章仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。如有侵权请邮件与我们联系处理。

Mail To:Admin@SybaseBbs.com