首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > VFP >

关于变量声明的疑惑解决思路

2012-02-03 
关于变量声明的疑惑经常看到一些高手在所写代码中声明变量时使用如下格式:PRIVATE Var1, Var2LOCAL Var1,

关于变量声明的疑惑
经常看到一些高手在所写代码中声明变量时使用如下格式:

PRIVATE Var1, Var2
LOCAL Var1, Var2

为何要同时声明两种不同类型的同名变量?有什么好处?
我知道 Private 可用来声明并隐藏高层模块中的变量,Local 用来声明局部变量
主要是为何要使用 Private 声明?


[解决办法]
学习~
[解决办法]
我想他们至少都会遵循“变量使用前都应先赋初值”这条编程准则的:
在VFP中,LOCA变量初值为F
Variables and arrays created with LOCAL are initialized to False (.F.).
[解决办法]

探讨
TO :FOXHENGXING
"PRIVATE 不会创建内存变量(PRIVATE doesn't create variables;)"
不是我说的,是VFP帮助中说的。

[解决办法]


23 FOXHENGXING 版主,你这说法我就不同意了,private,local都是声明变量的,主要就是变量作用域的不同,没有说PRIVATE 不会创建内存变量的说法,不要误导大家。。

[解决办法]
回帖是一种美德!每天回帖即可获得 10 分可用分! 小技巧:教您如何更快获得可用分
[解决办法]
探讨
23 FOXHENGXING 版主,你这说法我就不同意了,private,local都是声明变量的,主要就是变量作用域的不同,没有说PRIVATE 不会创建内存变量的说法,不要误导大家。。


这个说法不对。 private 不创建变量,也不是声明变量。仅是把上层定义的变量隐藏起来对下面不可见。

[解决办法]
学习。
[解决办法]
a=1
=down()

Procedure Down 
LOCAL a 
PRIVATE a
a= 50 
? 'la' 
? a 
=OOK()
?'la'
?a
Return 
Endproc 

Procedure OOK 
a=a+1 
? 'OK' 
? a 
Return 
Endproc 


我尝试这样声明就不会出错!
[解决办法]
探讨
如果是偶尔一两个函数中这样使用,且只对某几个变量这样处理,可以理解为不想后面的程序使用这些变量
但从 39 楼中列举的代码来看,不是这种目的,况且所有方法/函数都是这样声明的
这样就可能出现我 33 楼所做的假设:不利于代码升级维护,可能因添加新代码而产生意料不到的 bug
只是现在还不知高手们这样做时,是否有他们自己的编程规范来避免此问题

[解决办法]
要敢于否认高手的写法问题!

PRIVATE 应该是原来老版本foxpro的
后来有了LOCAL,其实我觉得PRIVATE没有存在的必要呢
后来的vfp 保留了PRIVATE 是兼容需要

高手那么做的原因,是处于对LOCAL的怀疑,再加一道安全线(或者以前老的书写习惯的延续)
就好像有人喜欢在scan 面前加上go top 才能放心一样

[解决办法]
各们高手们钻角了,其实我认为楼主的这个疑惑很对,因为像十豆三说的一样,VFP的变量只要赋值也就定义了,楼主的困惑也就出在这“不用定义就可以使用”上了,其实两句同时用而且“是AND而不是OR”是因为这样从语法角度是规范的,先藏再建,而平时只用其中一个,对于VFP好像不出问题,但对于其它语言这个习惯就不好了,肯定出问题!
虽然单独用其中一个看起来作用一样,但道理不一样,单独用PRIVATE是声明“藏”了,但没创建,只所以看到创建了,是因为后边的赋值语句造成,而不是PRIVATE,而单独用LOCAL 虽然没明着“藏”,但你不藏就要把上层已经存在的变量声明成一个局部变量,VFP就只好自己想办法把上层的“藏”了再创建一个你需要的局部变量,满足一下一个不负责人的程序员要求。
所以我觉得VFP算得上老好人一个了,大家也不用争这个了,多多支持、帮助VFP和VFPER!
[解决办法]
最小再现环境如下:

将以下代码保存成 aa.prg,假设这个 aa.prg 是一个公用模块。
*---------------------------
* Private lcShortMenuName, lnIndex
Local lcShortMenuName, lnIndex

lcShortMenuName = Sys(2015)
lnIndex = 200

Define Popup (m.lcShortMenuName) ShortCut Relative From MRow(), MCol()

Define Bar 1 Of (m.lcShortMenuName) Prompt "菜单一"
Define Bar 2 Of (m.lcShortMenuName) Prompt "菜单二"

On Selection Bar 1 Of (m.lcShortMenuName) m.lnIndex = Bar()
On Selection Bar 2 Of (m.lcShortMenuName) m.lnIndex = Bar()

Activate Popup (m.lcShortMenuName)
Deactivate Popup (m.lcShortMenuName)
Release Popups (m.lcShortMenuName)



Messagebox(Transform(m.lnIndex))
*---------------------------

运行 aa.prg 应该一切正常。好的,再把下面的代码保存在 a.prg,并且假设这个 a.prg 中的 lnIndex 就必须是静态变量,因为可能还有 cc.prg,dd.prg 需要用到 lnIndex 的值。

*---------------------------
lnIndex = 100

aa()
*---------------------------

运行 a .prg,结果很是令人吃惊甚至可以用诡异来形容,然后你再去掉 aa.prg 中首行的 Private 注释,结果又是正确的了。测试结果很明显,显然在 aa.Prg 中的 Local 不起作用了,但加上 Private 则又正确地保护了变量,我无法解释为什么 aa.prg 中不加 Private 就会错了,只能称之为灵异事件,或者 vfp 本身在变量管理上,存在问题。

按这个思路沿伸下去:如果 aa.prg 是一个公用过程或者公用类或者公用模块,显然我们不能预言并要求所有调用 aa.prg 的过程都不允许出现静态变量,但如果有任意一个静态变量跟 aa.prg 中 Local 中的变量同名,那显然很糟。

最后说一句,不要以为是快捷菜单的问题,只不过我发现用快捷菜单能用最少的代码再现这个问题。所以我在公用模块中,一般都要加上 Private 。可请 dkfdtf 再次核实,会发现我仅在类代码有这样使用,而在表单或者过程,则并没有这样子使用。我的公用模块中加 Private 是为了保证公用模块能正确执行,并且不会干扰任何调用公用模块的静态变量,也保证不受其静态变量的干扰。
[解决办法]
在子程序Z1中,直接给p001=2,其结果在 Z2 子程序Z1中,p001 变量显示为 2 

CLEAR 
p001=1 
Z1() 
?"主程序的值:"+STR(p001) 
RELEASE p001 

FUNCTION Z1 
PRIVATE p001 
p001=2 
Z2() 


FUNCTION Z2 
?IIF(VARTYPE(p001)="U","p001变量不存在!","Z2的值:"+STR(p001)) 

热点排行