标题:求教:VFP的函数调用,形参究竟有没有“默认参数值”的概念?
只看楼主
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
结帖率:100%
 问题点数:0 回复次数:9 
求教:VFP的函数调用,形参究竟有没有“默认参数值”的概念?
刚才读VFP系统自带的“类管理器”(xsource - browser)的源码,读到一句函数调用,产生了这个疑惑。
xsource存放在VFP安装目录下的"Tools\xsource"内,“类管理器”在xsource的子目录“browser”内,或见附件:
browser.rar (388.35 KB)

browser.SCX表单中,“查看代码”按钮cmdExport.Click()代码是:
RETURN thisform.ExportClass(.T.)

而thisform.ExportClass方法代码是:
LPARAMETERS tcAlias,tcExportToFile
LOCAL lvResult
this.vResult=.T.
DO brwExportView IN browser WITH (this),(tcAlias),(tcExportToFile)
...

毕竟是微软提供的代码,而非自己写的,我找了半天,始终未查到形参tcExportToFile是什么东东?
初以为是全局变量,又不太可能。看名字,猜可能是“输出至.prg或.txt时指定的默认文件名”吧。
可,这ExportClass方法的LPARAMETERS指定了2个形参,也没法像VB那样,指定第2个形参的默认值:
lPARAMETERS tcAlias,tcExportToFile = "viewcode.prg"
然而调用此方法时,却只传递了第1个参数.T.,第2个参数忽略掉了。
那么,在VFP中,第2个形参未被显式赋值,则其默认参数值为tcExportToFile = .f.,对吗?
在第4行甚至还用到了这个被省略掉的参数值,再直接拿它去调用另一子程序brwExportView()

现在问题来啦,VFP能否像VB那样,显式地、主动地更改一个函数形参的“默认参数值”?




[此贴子已经被作者于2022-11-22 18:36编辑过]

搜索更多相关主题的帖子: VFP 形参 默认 调用 参数 
2022-11-22 12:34
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
得分:0 
tcExportToFile 是你要输出的文件名。
2022-11-22 15:15
gs2536785678
Rank: 10Rank: 10Rank: 10
等 级:贵宾
威 望:45
帖 子:565
专家分:1668
注 册:2017-7-16
得分:0 
在子程序里面还嵌入子程序,难于理解也很正常。
只有请出创作者,才能说得清楚了。
我的认识是,形式参数是没有【默认值】这一概念的。


[此贴子已经被作者于2022-11-22 16:13编辑过]

2022-11-22 15:57
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
得分:0 
找出brwExportClass函数,顺藤摸瓜。

brwExportView 里肯定有tcExportToFile的默认文件名参数,应该就是"viewcode.prg",当没有指定文件名参数时,系统就以viewcode.prg来命名,所以我们每次看到的都是这个文件名!


[此贴子已经被作者于2022-11-22 20:35编辑过]

2022-11-22 20:29
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
顶楼的最后一句话,有一定的误导性,不太厚道,呵呵呵呵。
其实我非常肯定:
vfp的形式参数,并没有类似其他语言那种可自定义“默认参数值”的语法。
具体出处我记不得,毕竟vfp已是十几年前玩过的东西了。
xsource的开源代码,则甚至更加古老,它是vfp 3.0年代的活化石代码,无时代意义。
故而,今天再看时,就几乎没办法习惯了。
本帖唯一可能有点儿用的结论是:
在调用函数时,若实参个数少于形参个数,则右边省略的实参,一律 =.F.。
也可不太严格地理解为:自右往左,缺失的形参默认值 =.F.
2022-11-22 23:39
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
得分:0 
FUNCTION brwExportView(toBrowser,tcAlias,tcExportToFile)
LOCAL lcExportToFile,lcAlias,lnLastSelect

IF toBrowser.AddInMethod("EXPORTVIEW")
    RETURN
ENDIF
lcAlias=IIF(EMPTY(tcAlias),toBrowser.cGallery,LOWER(ALLTRIM(tcAlias)))
IF NOT USED(lcAlias)
    toBrowser.vResult=.F.
    RETURN toBrowser.vResult
ENDIF
IF VARTYPE(tcExportToFile)=="C" AND NOT EMPTY(tcExportToFile)
    lcExportToFile=ALLTRIM(tcExportToFile)
ELSE
    lcExportToFile=LOWER(PUTFILE(M_SAVE_LOC,"","dbf")) &&这一句设置了默认值
ENDIF
IF EMPTY(lcExportToFile)
    toBrowser.vResult=.F.
    RETURN toBrowser.vResult
ENDIF
IF NOT ":"$lcExportToFile AND NOT "\\"$lcExportToFile
    lcExportToFile=LOWER(FULLPATH(lcExportToFile))
ENDIF
IF FILE(lcExportToFile)
    IF toBrowser.MsgBox(lcExportToFile+M_ALREADY_EXISTS_OVER_LOC,35)#6
        toBrowser.vResult=.F.
        RETURN toBrowser.vResult
    ENDIF
    ERASE (lcExportToFile)
    IF FILE(lcExportToFile)
        toBrowser.vResult=.F.
        RETURN toBrowser.vResult
    ENDIF
ENDIF
lnLastSelect=SELECT()
SELECT (lcAlias)
COPY TO (lcExportToFile)
SELECT (lnLastSelect)
ENDFUNC
2022-11-26 22:01
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
得分:0 
****parametertest.prg***
***一个简单的默认参数设置代码***
LPARAMETERS tcpara1
CLEAR
IF PARAMETERS()=0 AND tcpara1=.f.
    MESSAGEBOX("You missed the parameter of 'tcpara1'!")
    tcpara1="Say hello world!"
    ?"You have set the default parameter as " + '"'+tcpara1+'"'
    RETURN .f.
ENDIF

IF VARTYPE(tcpara1)#"C"
    MESSAGEBOX("Incorrect parameter type!")
    RETURN .f.
ELSE
    MESSAGEBOX("You have input a char parameter!")
    RETURN .t.
ENDIF
2022-11-26 22:42
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
以下是引用sam_jiang在2022-11-26 22:42:11的发言:

****parametertest.prg***
***一个简单的默认参数设置代码***
LPARAMETERS tcpara1


sam可能误会我意思啦。

我说的是,在vfp中无法类似vb等语言那样,非常优雅地、简洁地、一句话搞定地,给你例子中的tcpara1形参,设置一个预设值。比如,当别人以非空实参parametertest("tom")来调用时,tcpara1="tom";而当别人无实参调用parametertest(),则tcpara1="sam”,自动取自定义的预设值,而非预设值一律只能得到.f.。

接收参数之后,再手动用代码if....endif去判断参数是空或者非空,这确实是退而求其次的标准作法。

假如,函数有5个形参甚至更多几个,自左往右,程序调用时只传递了2个实参,剩下的3个取预设值,那么,手动if...endif就非常繁琐易错……怎么说呢,用楼主的口头禅说——很不优雅。对吧?

或,尽可能折中一下,尽可能优雅一下子——

*------------------
FUNCTION testpara(tc1, tc2, tc3)
tc1 = iif(! empty(tc1), tc1, "Tom")
tc2 = iif(! empty(tc2), tc2, "Sam")
tc3 = iif(! empty(tc3), tc3, "John")
******************
* 巴拉巴拉,以下为函数的具体实现代码
* ...
* ...
******************
? tc1, tc2, tc3
return
*------------------

testpara("apple")
testpara("apple", "banana")
testpara("apple", "banana", "William")


[此贴子已经被作者于2022-11-27 12:09编辑过]

2022-11-27 09:37
cssnet
Rank: 4
等 级:业余侠客
威 望:4
帖 子:317
专家分:203
注 册:2013-10-4
得分:0 
再想深一层。
LPARAMETERS无非也就相当于Local。所谓形式参数,无非也就相当于在函数头声明局部变量,其作用域为函数级的,只不过特殊了一点。
特殊的一点在于,LPARA自动接收函数调用者传来的实参值,并在函数初始化时,自动赋值给对应位置的形参变量。至于缺失实参值的,就自动为形参变量赋初始值 = .F.(其实任何变量,若不显式地赋值,其初始值皆 = .F.)。
楼主平素是有“代码洁癖”的家伙,故而一直对自动赋初始值的方式方法耿耿于怀而已。
倘若抛开“洁癖”,VB形式的函数形参默认值,其内部实现过程,也就大致对应于8#的代码了。
2022-11-27 15:00
sam_jiang
Rank: 8Rank: 8
等 级:贵宾
威 望:10
帖 子:542
专家分:781
注 册:2021-10-13
得分:0 
2022-11-27 19:22



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-510733-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.436648 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved