Functions - Definition & Usage - AutoHotkey
文章推薦指數: 80 %
[AHK_L 60+]: If something other than a modifiable variable is passed to a ByRef parameter, the function behaves as though the keyword "ByRef" is absent. For ...
Functions
TableofContents
IntroductionandSimpleExamples
Parameters
OptionalParameters
ReturningValuestoCaller
VariadicFunctions
LocalVariables
DynamicallyCallingaFunction
Short-circuitBooleanEvaluation
UsingSubroutinesWithinaFunction
Return,Exit,andGeneralRemarks
Using#IncludetoShareFunctionsAmongMultipleScripts
LibrariesofFunctions:StandardLibraryandUserLibrary
Built-inFunctions
IntroductionandSimpleExamples
Afunctionissimilartoasubroutine(Gosub)exceptthatitcanacceptparameters(inputs)fromitscaller.Inaddition,afunctionmayoptionallyreturnavaluetoitscaller.Considerthefollowingsimplefunctionthatacceptstwonumbersandreturnstheirsum:
Add(x,y)
{
returnx+y;"Return"expectsanexpression.
}
Theaboveisknownasafunctiondefinitionbecauseitcreatesafunctionnamed"Add"(notcasesensitive)andestablishesthatanyonewhocallsitmustprovideexactlytwoparameters(xandy).Tocallthefunction,assignitsresulttoavariablewiththe:=operator.Forexample:
Var:=Add(2,3);Thenumber5willbestoredinVar.
Also,afunctionmaybecalledwithoutstoringitsreturnvalue:
Add(2,3)
Butinthiscase,anyvaluereturnedbythefunctionisdiscarded;sounlessthefunctionproducessomeeffectotherthanitsreturnvalue,thecallwouldservenopurpose.
Sinceafunctioncallisanexpression,anyvariablenamesinitsparameterlistshouldnotbeenclosedinpercentsigns.Bycontrast,literalstringsshouldbeenclosedindoublequotes.Forexample:
ifInStr(MyVar,"fox")
MsgBoxThevariableMyVarcontainsthewordfox.
Finally,functionsmaybecalledintheparametersofanycommand(exceptOutputVarandInputVarparameterssuchasthoseofStringLen).However,parametersthatdonotsupportexpressionsmustusethe"%"prefixasinthisexample:
MsgBox%"Theansweris:".Add(3,2)
The"%"prefixisalsopermittedinparametersthatnativelysupportexpressions,butitissimplyignored.
Parameters
Whenafunctionisdefined,itsparametersarelistedinparenthesesnexttoitsname(theremustbenospacesbetweenitsnameandtheopen-parenthesis).Ifafunctiondoesnotacceptanyparameters,leavetheparenthesesempty;forexample:GetCurrentTimestamp().
ByRefParameters:Fromthefunction'spointofview,parametersareessentiallythesameaslocalvariablesunlesstheyaredefinedasByRefasinthisexample:
Swap(ByRefLeft,ByRefRight)
{
temp:=Left
Left:=Right
Right:=temp
}
Intheexampleabove,theuseofByRefcauseseachparametertobecomeanaliasforthevariablepassedinfromthecaller.Inotherwords,theparameterandthecaller'svariablebothrefertothesamecontentsinmemory.ThisallowstheSwapfunctiontoalterthecaller'svariablesbymovingLeft'scontentsintoRightandviceversa.
Bycontrast,ifByRefwerenotusedintheexampleabove,LeftandRightwouldbecopiesofthecaller'svariablesandthustheSwapfunctionwouldhavenoexternaleffect.
Sincereturncansendbackonlyonevaluetoafunction'scaller,ByRefcanbeusedtosendbackextraresults.Thisisachievedbyhavingthecallerpassinavariable(usuallyempty)inwhichthefunctionstoresavalue.
Whenpassinglargestringstoafunction,ByRefenhancesperformanceandconservesmemorybyavoidingtheneedtomakeacopyofthestring.Similarly,usingByReftosendalongstringbacktothecallerusuallyperformsbetterthansomethinglikeReturnHugeString.
[AHK_L60+]:IfsomethingotherthanamodifiablevariableispassedtoaByRefparameter,thefunctionbehavesasthoughthekeyword"ByRef"isabsent.Forexample,Swap(A_Index,i)storesthevalueofA_Indexini,butthevalueassignedtoLeftisdiscardedoncetheSwapfunctionreturns.
[v1.1.01+]:TheIsByRef()functioncanbeusedtodeterminewhetherthecallersuppliedavariableforagivenByRefparameter.
Knownlimitations:
FieldsofobjectsarenotconsideredvariablesforthepurposesofByRef.Forexample,iffoo.barispassedtoaByRefparameter,itwillbehaveasthoughByRefwasomitted.
ItisnotpossibletopassClipboard,built-invariables,orenvironmentvariablestoafunction'sByRefparameter,evenwhen#NoEnvisabsentfromthescript.
Althoughafunctionmaycallitselfrecursively,ifitpassesoneofitsownlocalvariablesornon-ByRefparameterstoitselfByRef,thenewlayer'sByRefparameterwillrefertoitsownlocalvariableofthatnameratherthanthepreviouslayer's.However,thisissuedoesnotoccurwhenafunctionpassestoitselfaglobalvariable,staticvariable,orByRefparameter.
Ifaparameterinafunction-callresolvestoavariable(e.g.Varor++VarorVar*=2),otherparameterstoitsleftorrightcanalterthatvariablebeforeitispassedtothefunction.Forexample,MyFunc(Var,Var++)wouldunexpectedlypass1and0whenVarisinitially0,evenwhenthefunction'sfirstparameterisnotByRef.Sincethisbehavioriscounterintuitive,itmightchangeinafuturerelease.
ByRefisnotdirectlysupportedinfunctionscalledbyCOMclients,orwhencallingCOMmethods.Instead,thescriptreceivesormustpassawrapperobjectcontainingtheVarTypeandaddressofthevalue.
OptionalParameters
Whendefiningafunction,oneormoreofitsparameterscanbemarkedasoptional.Thisisdonebyappending:=(in[v1.1.09]orlater)or=,followedbytheparameter'sdefaultvalue,whichmustbeoneofthefollowing:true,false,aliteralinteger,aliteralfloatingpointnumber,oraquoted/literalstringsuchas"fox"or""(butstringsinversionspriorto[v1.0.46.13]supportonly"").
Theuseof=(withoutacolon)ispermittedforbackward-compatibility,butnotrecommended,andwillnotbepermittedbyAutoHotkeyv2.Regardlessofwhichoperatorisused,defaultvalueswhicharestringsmustalwaysbeenclosedinquotemarks.
ThefollowingfunctionhasitsZparametermarkedoptional:
Add(X,Y,Z:=0){
returnX+Y+Z
}
Whenthecallerpassesthreeparameterstothefunctionabove,Z'sdefaultvalueisignored.Butwhenthecallerpassesonlytwoparameters,Zautomaticallyreceivesthevalue0.
Itisnotpossibletohaveoptionalparametersisolatedinthemiddleoftheparameterlist.Inotherwords,allparametersthatlietotherightofthefirstoptionalparametermustalsobemarkedoptional.[AHK_L31+]:Optionalparametersmaybeomittedfromthemiddleoftheparameterlistwhencallingthefunction,asshownbelow.Fordynamicfunctioncallsandmethodcalls,thisrequires[v1.1.12+].
MyFunc(1,,3)
MyFunc(X,Y:=2,Z:=0){;NotethatZmuststillbeoptionalinthiscase.
MsgBox%X%,%Y%,%Z%
}
[v1.0.46.13+]:ByRefparametersalsosupportdefaultvalues;forexample:MyFunc(ByRefp1="").Wheneverthecalleromitssuchaparameter,thefunctioncreatesalocalvariabletocontainthedefaultvalue;inotherwords,thefunctionbehavesasthoughthekeyword"ByRef"isabsent.
ReturningValuestoCaller
Asdescribedinintroduction,afunctionmayoptionallyreturnavaluetoitscaller.
Test:=returnTest()
MsgBox%Test
returnTest(){
return123
}
Ifyouwanttoreturnextraresultsfromafunction,youmayalsouseByRef:
returnByRef(A,B,C)
MsgBox%A","B","C
returnByRef(ByRefval1,ByRefval2,ByRefval3)
{
val1:="A"
val2:=100
val3:=1.1
return
}
[v1.0.97+]:ObjectsandArrayscanbeusedtoreturnmultiplevaluesorevennamedvalues:
Test1:=returnArray1()
MsgBox%Test1[1]","Test1[2]
Test2:=returnArray2()
MsgBox%Test2[1]","Test2[2]
Test3:=returnObject()
MsgBox%Test3.id","Test3.val
returnArray1(){
Test:=[123,"ABC"]
returnTest
}
returnArray2(){
x:=456
y:="EFG"
return[x,y]
}
returnObject(){
Test:={id:789,val:"HIJ"}
returnTest
}
VariadicFunctions[AHK_L60+]
Whendefiningafunction,writeanasteriskafterthefinalparametertomarkthefunctionasvariadic,allowingittoreceiveavariablenumberofparameters:
Join(sep,params*){
forindex,paraminparams
str.=param.sep
returnSubStr(str,1,-StrLen(sep))
}
MsgBox%Join("`n","one","two","three")
Whenavariadicfunctioniscalled,surplusparameterscanbeaccessedviaanobjectwhichisstoredinthefunction'sfinalparameter.Thefirstsurplusparameterisatparams[1],thesecondatparams[2]andsoon.Aswithanystandardobject,params.MaxIndex()canbeusedtodeterminethehighestnumericindex(inthiscasethenumberofparameters).However,iftherearenoparameters,MaxIndexreturnsanemptystring.
Notes:
The"variadic"parametercanonlyappearattheendoftheformalparameterlist.
RegExcalloutscannotbevariadic;the"variadic"parameteristoleratedbutleftblank.
Callbackspasssurplusparametersbyaddressratherthanviaanarray.
VariadicFunctionCalls
Whilevariadicfunctionscanacceptavariablenumberofparameters,anarrayofparameterscanbepassedtoanyfunctionbyapplyingthesamesyntaxtoafunction-call:
substrings:=["one","two","three"]
MsgBox%Join("`n",substrings*)
Notes:
Numberingofparameterswithinthesourcearraybeginsat1.
Optionalparametersmaybeentirelyomittedfromthearray.
Thearrayofparametersmaycontainnameditemswhencallingauser-definedfunction;inanyothercase,nameditemsarenotsupported.
Thetargetfunctionmayalsobevariadic,inwhichcasenameditemsarecopiedeveniftheyhavenocorrespondingformalparameter.
Thissyntaxcanalsobeusedwhencallingmethodsorretrievingpropertiesofobjects;forexample,Object.Property[Params*].[v1.1.12+]:Itcanalsobeusedforsettingproperties.
Knownlimitations:
Onlytheright-mostparametercanbeexpandedthisway.Forexample,MyFunc(x,y*)issupportedbutMyFunc(x*,y)isnot.
Theremustnotbeanynon-whitespacecharactersbetweentheasterisk(*)andthesymbolwhichendstheparameterlist.
LocalandGlobalVariables
LocalVariables
Localvariablesarespecifictoasinglefunctionandarevisibleonlyinsidethatfunction.Consequently,alocalvariablemayhavethesamenameasaglobalvariableandbothwillhaveseparatecontents.Separatefunctionsmayalsosafelyusethesamevariablenames.
Alllocalvariableswhicharenotstaticareautomaticallyfreed(madeempty)whenthefunctionreturns.
Built-invariablessuchasClipboard,ErrorLevel,andA_TimeIdleareneverlocal(theycanbeaccessedfromanywhere),andcannotberedeclared.
Functionsareassume-localbydefault.Variablesaccessedorcreatedinsideanassume-localfunctionarelocalbydefault,withthefollowingexceptions:
Super-globalvariables,includingclasses.
Adynamicvariablereferencemayresolvetoanexistingglobalvariableifnolocalvariableexistsbythatname.
Commandsthatcreatepseudo-arraysmaycreateallelementsasglobalevenifonlythefirstelementisdeclared.
Thedefaultmayalsobeoverriddenasshownbelow(bydeclaringthevariableorbychangingthemodeofthefunction).
Force-localmode[v1.1.27+]:Ifthefunction'sfirstlineistheword"local",allvariablereferences(evendynamicones)areassumedtobelocalunlesstheyaredeclaredasglobalinsidethefunction.Unlikethedefaultmode,force-localmodehasthefollowingbehavior:
Super-globalvariables(includingclasses)cannotbeaccessedwithoutdeclaringtheminsidethefunction.
Dynamicvariablereferencesfollowthesamerulesasnon-dynamicones.Onlyglobalvariableswhicharedeclaredinsidethefunctioncanbeaccessed.
StringSplitandothercommandswhichcreatepseudo-arraysfollowthesamerulesasnon-dynamicvariablereferences(avoidingacommonsourceofconfusion).
TheLocalSameAsGlobalwarningisneverraisedforvariableswithinaforce-localfunction.
Globalvariables
Torefertoanexistingglobalvariableinsideafunction(orcreateanewone),declarethevariableasglobalpriortousingit.Forexample:
LogToFile(TextToLog)
{
globalLogFileName;Thisglobalvariablewaspreviouslygivenavaluesomewhereoutsidethisfunction.
FileAppend,%TextToLog%`n,%LogFileName%
}
Assume-globalmode:Ifafunctionneedstoaccessorcreatealargenumberofglobalvariables,itcanbedefinedtoassumethatallitsvariablesareglobal(exceptitsparameters)bymakingitsfirstlineeithertheword"global"orthedeclarationofalocalvariable.Forexample:
SetDefaults()
{
global;Thiswordmaybeomittedifthefirstlineofthisfunctionwillbesomethinglike"localMyVar".
MyGlobal:=33;Assigns33toaglobalvariable,firstcreatingthevariableifnecessary.
localx,y:=0,z;Localvariablesmustbedeclaredinthismode,otherwisetheywouldbeassumedglobal.
}
Thisassume-globalmodecanalsobeusedbyafunctiontocreateaglobalarray,suchasaloopthatassignsvaluestoArray%A_Index%.
Super-globalvariables[v1.1.05+]:Ifaglobaldeclarationappearsoutsideofanyfunction,ittakeseffectforallfunctionsbydefault(excludingforce-localfunctions).Thisavoidstheneedtoredeclarethevariableineachfunction.However,ifafunctionparameterorlocalvariablewiththesamenameisdeclared,ittakesprecedenceovertheglobalvariable.Variablescreatedbytheclasskeywordarealsosuper-global.
Staticvariables
Staticvariablesarealwaysimplicitlylocal,butdifferfromlocalsbecausetheirvaluesarerememberedbetweencalls.Forexample:
LogToFile(TextToLog)
{
staticLoggedLines:=0
LoggedLines+=1;Maintainatallylocally(itsvalueisrememberedbetweencalls).
globalLogFileName
FileAppend,%LoggedLines%:%TextToLog%`n,%LogFileName%
}
StaticInitializers:Inversionspriorto1.0.46,allstaticvariablesstartedoffblank;sotheonlywaytodetectthatonewasbeingusedforthefirsttimewastocheckwhetheritwasblank.[v1.0.46+]:Astaticvariablemaybeinitializedtosomethingotherthan""byfollowingitwith:=or=followedbyoneofthefollowing:true,false,aliteralinteger,aliteralfloatingpointnumber,oraliteral/quotedstringsuchas"fox".Forexample:staticX:=0,Y:="fox".Eachstaticvariableisinitializedonlyonce(beforethescriptbeginsexecuting).
[AHK_L58+]:Staticvar:=expressionissupported.Allsuchexpressionsareevaluatedimmediatelybeforethescript'sauto-executesectionintheordertheyareencounteredinthescript.
Assume-staticmode[v1.0.48+]:Afunctionmaybedefinedtoassumethatallitsvariablesarestatic(exceptitsparameters)bymakingitsfirstlinetheword"static".Forexample:
GetFromStaticArray(WhichItemNumber)
{
static
staticFirstCallToUs:=true;Astaticdeclaration'sinitializerstillrunsonlyonce(uponstartup).
ifFirstCallToUs;Createastaticarrayduringthefirstcall,butnotonsubsequentcalls.
{
FirstCallToUs:=false
Loop10
StaticArray%A_Index%:="Value#".A_Index
}
returnStaticArray%WhichItemNumber%
}
Inassume-staticmode,anyvariablethatshouldnotbestaticmustbedeclaredaslocalorglobal(withthesameexceptionsasforassume-localmode,unlessforce-localmodeisalsoineffect).
[v1.1.27+]:Force-localmodecanbecombinedwithassume-staticmodebyspecifyinglocalandthenstatic,asshownbelow.Thisallowsthefunctiontouseforce-localrulesbutcreatevariablesasstaticbydefault.
globalMyVar:="Thisisglobal"
DemonstrateForceStatic()
DemonstrateForceStatic()
{
local
static
MyVar:="Thisisstatic"
ListVars
MsgBox
}
Moreaboutlocalsandglobals
Multiplevariablesmaybedeclaredonthesamelinebyseparatingthemwithcommasasintheseexamples:
globalLogFileName,MaxRetries:=5
staticTotalAttempts:=0,PrevResult
[v1.0.46+]:Alocalorglobalvariablemaybeinitializedonthesamelineasitsdeclarationbyfollowingitwith:=or=followedbyanyexpression(the=operatorbehavesthesameas:=indeclarations).Unlikestaticinitializers,theinitializersoflocalsandglobalsexecuteeverytimethefunctioniscalled,butonlyif/whentheflowofcontrolactuallyreachesthem.Inotherwords,alinelikelocalx:=0hasthesameeffectaswritingtwoseparatelines:localxfollowedbyx:=0.
Becausethewordslocal,global,andstaticareprocessedimmediatelywhenthescriptlaunches,avariablecannotbeconditionallydeclaredbymeansofanIFstatement.Inotherwords,adeclarationinsideanIF'sorELSE'sblocktakeseffectunconditionallyforalllinesbetweenthedeclarationandthefunction'sclosingbrace.AlsonotethatitisnotcurrentlypossibletodeclareadynamicvariablesuchasglobalArray%i%.
Forcommandsthatcreatepseudo-arrays(suchasStringSplit),eachvariableintheresultingpseudo-arrayislocaliftheassume-globalmodeisnotineffectorifthepseudo-array'sfirstelementhasbeendeclaredasalocalvariable(thisisalsotrueifoneofthefunction'sparametersispassed--evenifthatparameterisByRef--becauseparametersaresimilartolocalvariables).Conversely,ifthefirstelementhasbeendeclaredglobal,aglobalarrayiscreated.However,thecommonsourceofconfusionbelowapplieseveninthesecases.ThefirstelementforStringSplitisArrayName0.Forotherarray-creatingcommandssuchasWinGetList,thefirstelementisArrayName(i.e.withoutthenumber).[v1.1.27+]:Whenforce-localmodeisineffect,thesecommandsfollowrulesconsistentwithnormalvariablereferences;thatis,anypseudo-arrayelementnotdeclaredasglobalwillbelocalevenifotherelementsaredeclaredglobal.
Withinafunction(unlessforce-localmodeisineffect),anydynamicvariablereferencesuchasArray%i%alwaysresolvestoalocalvariableunlessnovariableofthatnameexists,inwhichcaseaglobalisusedifitexists.Ifneitherexistsandtheusagerequiresthevariabletobecreated,itiscreatedasalocalvariableunlesstheassume-globalmodeisineffect.Consequently,afunctioncancreateaglobalarraymanually(bymeanssuchasArray%i%:=A_Index)onlyifithasbeendefinedasanassume-globalfunction.
Commonsourceofconfusion:Anynon-dynamicreferencetoavariablecreatesthatvariablethemomentthescriptlaunches.Forexample,whenusedoutsideafunction,MsgBox%Array1%createsArray1asaglobalthemomentthescriptlaunches.Conversely,whenusedinsideafunctionMsgBox%Array1%createsArray1asoneofthefunction'slocalsthemomentthescriptlaunches(unlessassume-globalisineffect),evenifArrayandArray0aredeclaredglobal.
DynamicallyCallingaFunction
[v1.0.47.06+]:Afunction(evenabuilt-infunction)maybecalleddynamicallyviapercentsigns.Forexample,%Var%(x,"fox")wouldcallthefunctionwhosenameiscontainedinVar.Similarly,Func%A_Index%()wouldcallFunc1()orFunc2(),etc.,dependingonthecurrentvalueofA_Index.
[v1.1.07.00+]:Varin%Var%()cancontainafunctionnameorafunctionobject.Ifthefunctiondoesnotexist,thedefaultbaseobject's__Callmeta-functionisinvokedinstead.
Ifthefunctioncannotbecalledduetooneofthereasonsbelow,theevaluationoftheexpressioncontainingthecallstopssilentlyandprematurely,whichmayleadtoinconsistentresults:
Callinganonexistentfunction,whichcanbeavoidedbyusingIfIsFunc(VarContainingFuncName).Exceptforbuilt-infunctions,thecalledfunction'sdefinitionmustexistexplicitlyinthescriptbymeanssuchas#Includeoranon-dynamiccalltoalibraryfunction.
Passingtoofewparameters,whichcanbeavoidedbycheckingIsFunc()'sreturnvalue(whichisthenumberofmandatoryparametersplusone).[v1.0.48+]:Notethatpassingtoomanyparametersistolerated;eachextraparameterisfullyevaluated(includinganycallstofunctions)andthendiscarded.
Finally,adynamiccalltoafunctionisslightlyslowerthananormalcallbecausenormalcallsareresolved(lookedup)beforethescriptbeginsrunning.
Short-circuitBooleanEvaluation
WhenAND,OR,andtheternaryoperatorareusedwithinanexpression,theyshort-circuittoenhanceperformance(regardlessofwhetheranyfunctioncallsarepresent).Short-circuitingoperatesbyrefusingtoevaluatepartsofanexpressionthatcannotpossiblyaffectitsfinalresult.Toillustratetheconcept,considerthisexample:
if(ColorName!=""ANDnotFindColor(ColorName))
MsgBox%ColorName%couldnotbefound.
Intheexampleabove,theFindColor()functionnevergetscallediftheColorNamevariableisempty.ThisisbecausetheleftsideoftheANDwouldbefalse,andthusitsrightsidewouldbeincapableofmakingthefinaloutcometrue.
Becauseofthisbehavior,it'simportanttorealizethatanyside-effectsproducedbyafunction(suchasalteringaglobalvariable'scontents)mightneveroccurifthatfunctioniscalledontherightsideofanANDorOR.
Itshouldalsobenotedthatshort-circuitevaluationcascadesintonestedANDsandORs.Forexample,inthefollowingexpression,onlytheleftmostcomparisonoccurswheneverColorNameisblank.Thisisbecausetheleftsidewouldthenbeenoughtodeterminethefinalanswerwithcertainty:
if(ColorName=""ORFindColor(ColorName,Region1)ORFindColor(ColorName,Region2))
break;Nothingtosearchfor,oramatchwasfound.
Asshownbytheexamplesabove,anyexpensive(time-consuming)functionsshouldgenerallybecalledontherightsideofanANDorORtoenhanceperformance.Thistechniquecanalsobeusedtopreventafunctionfrombeingcalledwhenoneofitsparameterswouldbepassedavalueitconsidersinappropriate,suchasanemptystring.
[v1.0.46+]:Theternaryconditionaloperator(?:)alsoshort-circuitsbynotevaluatingthelosingbranch.
UsingSubroutinesWithinaFunction
Althoughafunctioncannotcontaindefinitionsofotherfunctions,itcancontainsubroutines.Aswithothersubroutines,useGosubtolaunchthemandReturntoreturn(inwhichcasetheReturnwouldbelongtotheGosubandnotthefunction).
Knownlimitation:Currently,thenameofeachsubroutine(label)mustbeuniqueamongthoseoftheentirescript.Theprogramwillnotifyyouuponlaunchifthereareduplicatelabels.
IfafunctionusesGosubtojumptoapublicsubroutine(onethatliesoutsideofthefunction'sbraces),allvariablesoutsideareglobalandthefunction'sownlocalvariablesarenotaccessibleuntilthesubroutinereturns.However,A_ThisFuncwillstillcontainthenameofthefunction.
AlthoughGotocannotbeusedtojumpfrominsideafunctiontooutside,itispossibleforafunctiontoGosubanexternal/publicsubroutineandthendoaGotofromthere.
AlthoughtheuseofGotoisgenerallydiscouraged,itcanbeusedinsideafunctiontojumptoanotherpositionwithinthesamefunction.Thiscanhelpsimplifycomplexfunctionsthathavemanypointsofreturn,allofwhichneedtodosomeclean-uppriortoreturning.
Afunctionmaycontainexternally-calledsubroutinessuchastimers,GUIg-labels,andmenuitems.Thisisgenerallydonetoencapsulatetheminaseparatefileforusewith#Include,whichpreventsthemfrominterferingwiththescript'sauto-executesection.However,thefollowinglimitationsapply:
Suchsubroutinesshoulduseonlystaticandglobalvariables(notlocals)iftheirfunctionisevercallednormally.Thisisbecauseasubroutinethreadthatinterruptsafunction-callthread(orviceversa)wouldbeabletochangethevaluesoflocalvariablesseenbytheinterruptedthread.Furthermore,anytimeafunctionreturnstoitscaller,allofitslocalvariablesaremadeblanktofreetheirmemory.
Suchsubroutinesshoulduseonlyglobalvariables(notstaticvariables)asGUIcontrolvariables.
Whenafunctionisenteredbyasubroutinethread,anyreferencestodynamicvariablesmadebythatthreadaretreatedasglobals(includingcommandsthatcreatearrays).
Return,Exit,andGeneralRemarks
Iftheflowofexecutionwithinafunctionreachesthefunction'sclosingbracepriortoencounteringaReturn,thefunctionendsandreturnsablankvalue(emptystring)toitscaller.AblankvalueisalsoreturnedwheneverthefunctionexplicitlyomitsReturn'sparameter.
WhenafunctionusestheExitcommandtoterminatethecurrentthread,itscallerdoesnotreceiveareturnvalueatall.Forexample,thestatementVar:=Add(2,3)wouldleaveVarunchangedifAdd()exits.Thesamethinghappensifafunctioncausesaruntimeerrorsuchasrunninganonexistentfile(whenUseErrorLevelisnotineffect).
AfunctionmayalterthevalueofErrorLevelforthepurposeofreturninganextravaluethatiseasytoremember.
Tocallafunctionwithoneormoreblankvalues(emptystrings),useanemptypairofquotesasinthisexample:FindColor(ColorName,"").
Sincecallingafunctiondoesnotstartanewthread,anychangesmadebyafunctiontosettingssuchasSendModeandSetTitleMatchModewillgointoeffectforitscallertoo.
Thecallerofafunctionmaypassanonexistentvariableorarrayelementtoit,whichisusefulwhenthefunctionexpectsthecorrespondingparametertobeByRef.Forexample,callingGetNextLine(BlankArray%i%)wouldcreatethevariableBlankArray%i%automaticallyasalocalorglobal(dependingonwhetherthecallerisinsideafunctionandwhetherithastheassume-globalmodeineffect).
Whenusedinsideafunction,ListVarsdisplaysafunction'slocalvariablesalongwiththeircontents.Thiscanhelpdebugascript.
StyleandNamingConventions
Youmightfindthatcomplexfunctionsaremorereadableandmaintainableiftheirspecialvariablesaregivenadistinctprefix.Forexample,namingeachparameterinafunction'sparameterlistwithaleading"p"or"p_"makestheirspecialnatureeasytodiscernataglance,especiallywhenafunctionhasseveraldozenlocalvariablescompetingforyourattention.Similarly,theprefix"r"or"r_"couldbeusedforByRefparameters,and"s"or"s_"couldbeusedforstaticvariables.
TheOneTrueBrace(OTB)stylemayoptionallybeusedtodefinefunctions.Forexample:
Add(x,y){
returnx+y
}
Using#IncludetoShareFunctionsAmongMultipleScripts
The#Includedirectivemaybeused(evenatthetopofascript)toloadfunctionsfromanexternalfile.
Explanation:Whenthescript'sflowofexecutionencountersafunctiondefinition,itjumpsoverit(usinganinstantaneousmethod)andresumesexecutionatthelineafteritsclosingbrace.Consequently,executioncanneverfallintoafunctionfromabove,nordoesthepresenceofoneormorefunctionsattheverytopofascriptaffecttheauto-executesection.
LibrariesofFunctions:StandardLibraryandUserLibrary[v1.0.47+]
Ascriptmaycallafunctioninanexternalfilewithouthavingtouse#Include.Forthistowork,afileofthesamenameasthefunctionmustexistinoneofthefollowinglibrarydirectories:
%A_ScriptDir%\Lib\;Locallibrary-requires[AHK_L42+].
%A_MyDocuments%\AutoHotkey\Lib\;Userlibrary.
directory-of-the-currently-running-AutoHotkey.exe\Lib\;Standardlibrary.
Forexample,ifascriptcallsanonexistentfunctionMyFunc(),theprogramsearchesforafilenamed"MyFunc.ahk"intheuserlibrary.Ifnotfoundthere,itsearchesforitinthestandardlibrary.Ifamatchisstillnotfoundandthefunction'snamecontainsanunderscore(e.g.MyPrefix_MyFunc),theprogramsearchesbothlibrariesforafilenamedMyPrefix.ahkandloadsitifitexists.ThisallowsMyPrefix.ahktocontainboththefunctionMyPrefix_MyFuncandotherrelatedfunctionswhosenamesstartwithMyPrefix_.
[AHK_L42+]:Thelocallibraryissupportedandissearchedbeforetheuserlibraryandstandardlibrary.
OnlyadirectfunctioncallsuchasMyFunc()cancausealibrarytobeauto-included.Ifthefunctionisonlycalleddynamicallyorindirectly,suchasbyatimerorGUIevent,thelibrarymustbeexplicitlyincludedinthescript.Forexample:#Include
延伸文章資訊
- 1函数| AutoHotkey
然而, 当函数传递给它自己全局变量, 静态变量或ByRef 参数时不会产生这样的问题. 如果一个参数在函数调用中被解析为一个变量(例如 Var 或 ++Var 或 Var*=2 ) ...
- 2Get String Value of passed ByRef Variable - Stack Overflow
ahk 002: myvar := "george" 003: passit(myvar) 007: MsgBox,GetOriginalVariableNameForSingleArgumen...
- 3函數- AutoHotKey.tw - Google Sites
同樣地, 使用ByRef 送回長字串給呼叫者通常比類似 Return HugeString 的方式執行的更好. [AHK_L 60+]: 如果傳遞給ByRef 參數的不是可修改的變數, 那麼函數...
- 4AutoHotkey-Scripts/Functions.ahk at master - GitHub
A collection of my AutoHotkey scripts and libraries - AutoHotkey-Scripts/Functions.ahk at master ...
- 5Functions - Definition & Usage - AutoHotkey
[AHK_L 60+]: If something other than a modifiable variable is passed to a ByRef parameter, the fu...