함수는 서브루틴 (Gosub)과 비슷합니다. 단, 호출자로부터 매개변수(입력)를 받을 수 있다는 점은 다릅니다. 게다가, 함수는 선택적으로 값을 호출자에게 돌려줄 수 있습니다. 다음의 간단한 함수를 연구해 보겠습니다. 두 개의 숫자를 받고 그 합을 돌려줍니다:
Add(x, y) { return x + y ; "Return"은 표현식을 기대합니다. }
위의 코드는 함수 정의라고 알려져 있는데 "Add" (대소문자 구분 없음)라는 이름의 함수를 생성하고 그 함수를 호출하려면 누구라도 정확하게 두 개의 매개변수 (x와 y)를 제공하도록 확립합니다. 이 함수를 호출하려면, :=연산자로 그의 결과를 변수에 할당합니다. 예를 들어:
Var := Add(2, 3) ; 숫자 5가 Var에 저장됩니다.
또, 함수는 그의 반환 값을 저장하지 않고서도 호출할 수 있습니다:
Add(2, 3)
그러나 이 경우, 함수가 돌려주는 값은 모두 폐기됩니다; 그래서 함수가 반환 값을 돌려주는 일 외에 다른 효과를 생산하지 않는 한, 이 호출은 어떤 목적에도 기여하지 못합니다.
함수 호출은 표현식이기 때문에, 매개변수 목록의 변수 이름은 퍼센트 사인으로 둘러싸지 않아도 됩니다. 대조적으로, 기호 문자열을 겹따옴표로 둘러 싸야 합니다. 예를 들어:
if InStr(MyVar, "fox") MsgBox 변수 MyVar에는 단어 fox가 들어 있습니다.
마지막으로, 함수는 다른 명령어의 매개변수에서 호출할 수도 있습니다 (StringLen의 매개변수와 같이 OutputVar와 InputVar 같은 매개변수는 예외입니다). 그렇지만, 표현식을 지원하지 않는 매개변수는 다음 예제와 같이 반드시 "% " 를 접두기호로 사용해야 합니다:
MsgBox % "정답은 다음과 같습니다: " . Add(3, 2)
"% " 접두기호는 또 근본적으로 표현식을 지원하는 매개변수에도 허용됩니다. 그러나 그냥 무시됩니다.
함수가 정의될 때, 그의 매개변수는 함수 이름 옆 괄호 안에 나열됩니다 (함수와 여는 괄호 사이에 공간이 있으면 안됩니다). 함수가 매개변수를 받지 않으면, 괄호를 빈 채로 둡니다: GetCurrentTimestamp()
.
ByRef 매개변수: 함수의 관점에서, 매개변수는 본질적으로 지역 변수와 똑같습니다. 그러나 다음 예제와 같이 ByRef로 정의된다면 다릅니다:
Swap(ByRef Left, ByRef Right) { temp := Left Left := Right Right := temp }
위의 예제에서, ByRef를 사용하면 각 매개변수들이 호출자로부터 들어오는 변수에 대하여 별명이 됩니다. 다른 말로, 매개변수와 호출자의 변수는 모두 메모리의 같은 내용을 가리킵니다. 이 때문에 Swap 함수는 호출자의 변수를 변경할 수 있습니다. Left의 내용을 Right으로 그리고 그 반대로 이동시킬 수 있습니다.
대조적으로, ByRef가 위의 예제에서 사용되지 않았다면, Left와 Right는 호출자 변수의 사본이 되어야 합니다. 그래서 Swap 함수는 외부적으로 아무 효과가 없을 것입니다.
return은 함수의 호출자에게 오직 하나의 값만 다시 돌려줄 수 있기 때문에, ByRef를 사용하면 추가 결과를 더 돌려줄 수 있습니다. 호출자에게 (보통 빈) 변수를 건네게 하고 거기에 함수가 값을 저장하면 됩니다.
방대한 문자열을 함수에 건넬 때, ByRef는 수행성능을 향상시키고 메모리를 그대로 유지합니다. 문자열의 사본을 만들 필요가 없기 때문입니다. 비슷하게, ByRef를 사용하여 긴 문자열을 다시 호출자에게 보내면 Return HugeString
와 같이 하는 것에 비해 보통 수행성능이 더 향상됩니다.
[AHK_L 60+]: 변경가능한 변수 말고 어떤 것이 ByRef 매개변수에 건네지면, 함수는 마치 키워드 "ByRef"가 없는 것처럼 행위합니다. 예를 들어, Swap(A_Index, i)
는 A_Index의 값을 i에 저장하지만, Left에 할당된 값은 Swap 함수가 반환되는 순간 폐기됩니다.
[v1.1.01+]: IsByRef() 함수를 사용하면 호출자가 주어진 ByRef 매개변수에 대하여 변수를 공급했는지 알 수 있습니다.
알려진 한계:
foo.bar
가 ByRef 매개변수에 건네지면, 마치 ByRef 키워드가 생략된 것처럼 행위합니다.Var
또는 ++Var
또는 Var*=2
), 왼쪽이나 오른쪽의 다른 매개변수들은 그 변수가 함수에 건네지기 전에 변경할 수 있습니다. 예를 들어, MyFunc(Var, Var++)
는 Var가 처음부터 0일 때 예상치 못하게 1과 0을 건네게 됩니다. 심지어 함수의 첫 매개변수가 ByRef가 아닐 때도 그렇습니다. 이 행위는 반직관적이기 때문에, 미래의 배포본에서는 바뀔 가능성이 있습니다.함수를 정의할 때, 하나 이상의 매개변수에 선택적 표식을 할 수 있습니다. This is done by appending :=
(in [v1.1.09] or later) or =
, followed by the parameter's default value, which must be one of the following: true
, false
, 문자 그대로의 정수, 문자 그대로의 부동 소수점 수, 또는 "fox" 또는 ""와 같이 인용부호처리되어 문자 그대로의 문자열. (그러나 [v1.0.46.13]이전 버전의 문자열은 오직 ""만 지원합니다).
The use of =
(without a colon) is permitted for backward-compatibility, but not recommended, and will not be permitted by AutoHotkey v2. Regardless of which operator is used, default values which are strings must always be enclosed in quote marks.
다음 함수는 Z 매개변수에 선택적 표식이 붙어 있습니다:
Add(X, Y, Z:=0) { return X + Y + Z }
호출자가 세 개의 매개변수를 위의 함수에 건네면, Z의 기본 값은 무시됩니다. 그러나 호출자가 오직 두 개의 매개변수만 건네면, Z는 자동으로 기본값 0을 받습니다.
선택적 매개변수를 리스트 한 가운데에 따로 배치하는 것은 불가능합니다. 다른 말로 하면, 첫 번째 선택적 매개변수의 오른쪽에 나오는 모든 매개변수도 역시 선택적으로 표식이 붙어야 합니다. [AHK_L 31+]: 선택적 매개변수는 매개변수 리스트의 중앙에서는 생략할 수 있습니다. 아래와 같이 함수를 호출합니다. 동적인 함수 호출과 메쏘드 호출은 [v1.1.12+]이상이 필요합니다.
MyFunc(1,, 3) MyFunc(X, Y:=2, Z:=0) { ; 이 경우 Z는여전히 선택적이어야 함에 유의합니다. MsgBox %X%, %Y%, %Z% }
[v1.0.46.13+]: ByRef 매개변수도 기본값을 지원합니다; 예를 들어: MyFunc(ByRef p1 = "")
. 호출자가 그런 매개변수를 빼먹을 때마다, 함수는 지역 변수를 만들어 기본 값을 담습니다; 다른 말로, 함수는 마치 키워드 "ByRef"가 존재하지 않는 것처럼 행위합니다.
소개에 기술한 바와 같이, 함수는 선택적으로 값을 호출자에게 돌려줄 수 있습니다.
Test := returnTest() MsgBox % Test returnTest() { return 123 }
함수로부터 결과를 더 많이 돌려주고 싶다면, ByRef를 사용할 수 있습니다:
returnByRef(A,B,C) MsgBox % A "," B "," C returnByRef(ByRef val1, ByRef val2, ByRef val3) { val1 := "A" val2 := 100 val3 := 1.1 return }
[v1.0.97+]: 객체와 배열을 사용하면 여러 값들 심지어 이름 붙은 값들도 돌려줄 수 있습니다:
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"] return Test } returnArray2() { x := 456 y := "EFG" return [x, y] } returnObject() { Test := {id: 789, val: "HIJ"} return Test }
함수를 정의할 때, 별표를 마지막 매개변수 뒤에 쓰면 그 함수를 가변함수로 만들 수 있습니다. 가변 개수의 매개변수를 받을 수 있습니다:
Join(sep, params*) { for index,param in params str .= param . sep return SubStr(str, 1, -StrLen(sep)) } MsgBox % Join("`n", "one", "two", "three")
가변 함수를 호출할 때, 넘치는 매개변수는 함수의 마지막 매개변수에 저장되어 있는 객체를 통하여 접근할 수 있습니다. 넘친 첫 번째 매개변수는 params[1]
에 있고, 두 번째는 params[2]
에 등등에 있습니다. 다른 표준 객체처럼params.MaxIndex()
를 사용하면 숫치상 가장 높은 인덱스를 알 수 있습니다 (이 경우 매개변수의 개수입니다). 그렇지만, 매개변수가 없다면, MaxIndex는 빈 문자열을 돌려줍니다.
주의:
가변 함수가 가변 개수의 매개변수를 받아들일 수 있는 반면, 매개변수 배열을 어떤 함수에도 건넬 수 있습니다. 같은 구문을 함수-호출에 적용하면 됩니다:
substrings := ["one", "two", "three"] MsgBox % Join("`n", substrings*)
주의:
Object.Property[Params*]
. [v1.1.12+]: 이에서는 특성을 설정하는 데에도 사용할 수 있습니다.알려진 한계:
MyFunc(x, y*)
는 지원하지만 MyFunc(x*, y)
는 지원하지 않습니다.*
)와 매개변수 리스트를 끝내는 심볼 사이에 공백문자말고 다른 문자는 허용하지 않습니다.Local variables are specific to a single function and are visible only inside that function. 결과적으로, 지역 변수는 전역 변수와 이름이 같을 수 있습니다. 그리고 서로 다른 내용을 가질 수 있습니다. Separate functions may also safely use the same variable names.
All local variables which are not static are automatically freed (made empty) when the function returns.
Built-in variables such as Clipboard, ErrorLevel, and A_TimeIdle are never local (they can be accessed from anywhere), and cannot be redeclared.
Functions are assume-local by default. Variables accessed or created inside an assume-local function are local by default, with the following exceptions:
The default may also be overridden as shown below (by declaring the variable or by changing the mode of the function).
Force-local mode [v1.1.27+]: If the function's first line is the word "local", all variable references (even dynamic ones) are assumed to be local unless they are declared as global inside the function. Unlike the default mode, force-local mode has the following behavior:
함수 안에서 기존의 전역 변수를 참조하려면 (또는 새로 만들려면), 변수를 global로 선언한 다음 사용합니다. 예를 들어:
LogToFile(TextToLog) { global LogFileName ; 이 전역 변수는 이 함수 바깥 어딘가에 미리 값이 주어져 있습니다. FileAppend, %TextToLog%`n, %LogFileName% }
전역-간주 모드: 함수가 방대한 개수의 전역 변수를 만들거나 접근할 필요가 있다면, 그의 모든 변수를 전역적으로 간주하도록 정의할 수 있습니다 (매개변수는 제외). 첫 줄을 단어 "global"로 만들거나 지역 변수의 선언으로 만들면 됩니다. 예를 들어:
SetDefaults() { global ; 함수의 첫 줄이 "local MyVar"와 같은 것으로 시작하면 이 단어는 생략해도 됩니다. MyGlobal := 33 ; 33을 전역 변수에 할당합니다. 필요하면 먼저 변수를 만듭니다. local x, y:=0, z ; 지역 변수는 이 모드로 선언해야 합니다. 그렇지 않으면 전역적으로 간주됩니다. }
전역-간주 모드를 함수에 사용하면 예를 들어 값을 Array%A_Index%
에 할당하는 회돌이와 같이 전역 배열을 만들 수 있습니다.
슈퍼-전역 변수 [v1.1.05+]: If a global declaration appears outside of any function, it takes effect for all functions by default (excluding force-local functions). 그래서 각 함수마다 해당 변수를 다시 선언할 필요가 없습니다. 그렇지만, 함수 매개변수나 지역 변수에 같은 이름이 선언되어 있다면, 전역 변수보다 우선 순위가 놓습니다. class 키워드로 만든 변수도 수퍼-전역 변수입니다.
정적 변수는 언제나 묵시적으로 지역적이지만, 지연 변수와는 다른 점이 있습니다. 호출 사이에 값을 기억합니다. 예를 들어:
LogToFile(TextToLog) { static LoggedLines := 0 LoggedLines += 1 ; 완전히 지역적으로 유지관리합니다 (그의 값은 호출 사이에 기억됩니다). global LogFileName FileAppend, %LoggedLines%: %TextToLog%`n, %LogFileName% }
정적 초기화자: 1.0.46 이전 버전에서, 모든 정적 변수는 빈 채로 시작했습니다; 그래서 처음으로 사용되는 변수인지 탐지하는 유일한 방법은 그것이 비어있는지 점검하는 것이었습니다. [v1.0.46+]: 정적 변수는 ""
말고 다른 것으로 초기화할 수 있습니다. 먼저 :=
이나 =
를 두고 바로 이어 다음 중 하나가 오면 됩니다: true
, false
, 기호 그대로의 숫자, 기호 그대로의 부동 소수점 수, 또는 "fox"
과 같이 기호 그대로/ 인용부호 처리된 문자열. 예를 들어: static X:=0, Y:="fox"
. 각 정적 변수는 (스크립트가 실행을 시작하기 전에) 오직 한 번만 초기화됩니다.
[AHK_L 58+]: Static var := expression
을 지원합니다. 그런 모든 표현식은 나타나는 순서대로 스크립트의 자동-실행 섹션 바로 앞에서 평가됩니다.
정적-간주 모드 [v1.0.48+]: 함수는 그의 모든 변수가 정적이라고 간주하도록 정의할 수 있습니다 (그의 매개변수는 제외). 첫 줄을 "static"이라는 단어로 만들면 됩니다. 예를 들어:
GetFromStaticArray(WhichItemNumber) { static static FirstCallToUs := true ; 정적 선언의 초기화자는 여전히 (기동시에) 한 번만 실행됩니다. if FirstCallToUs ; 첫 번째 호출 동안 정적 배열을 만듭니다. 그러나 그 다음 호출에는 만들지 않습니다. { FirstCallToUs := false Loop 10 StaticArray%A_Index% := "Value #" . A_Index } return StaticArray%WhichItemNumber% }
In assume-static mode, any variable that should not be static must be declared as local or global (with the same exceptions as for assume-local mode, unless force-local mode is also in effect).
[v1.1.27+]: Force-local mode can be combined with assume-static mode by specifying local
and then static
, as shown below. This allows the function to use force-local rules but create variables as static by default.
global MyVar := "This is global" DemonstrateForceStatic() DemonstrateForceStatic() { local static MyVar := "This is static" ListVars MsgBox }
많은 변수들을 한 줄에 선언할 수 있습니다. 다음 예제와 같이 쉼표로 가르면 됩니다:
global LogFileName, MaxRetries := 5 static TotalAttempts := 0, PrevResult
[v1.0.46+]: 전역 변수나 지역 변수는 선언과 동시에 같은 줄에서 초기화할 수 있습니다. :=
이나 =
다음에 표현식을 두면 됩니다 (=
연산자는 선언에서 :=
와 똑같이 행위합니다). 정적 초기화자와 다르게, 지역 변수와 전역 변수의 초기화자는 함수가 호출될 때마다 매번 실행됩니다. 그러나 오직 실행 흐름이 실제로 거기에 다다를 때에만 초기화합니다. 다른 말로, local x := 0
과 같은 줄은 다음과 같이 두 개의 서술문으로 작성한 것과 효과가 같습니다: local x
다음에 x := 0
.
local, global, 그리고 static같은 단어는 스크립트가 기동하자 마자 즉시 처리되기 때문에, 변수는 IF 서술문을 수단으로 하여 조건적으로 선언할 수 없습니다. 다른 말로 하면, IF 또는 ELSE 블록안에서 선언하면 해당 선언과 그 함수의 닫는 괄호 사이에 있는 모든 줄들에 예상치 못한 효과를 미칩니다. 또 주목할 것은 global Array%i%
와 같이 동적으로 변수를 선언하는 것은 현재 가능하지 않다는 것입니다.
(StringSplit 같은) 의사-배열을 생성하는 명령어에 대하여, 전역-간주 모드가 영향이 없거나 또는 의사-배열의 첫 번째 원소가 지역 변수로 선언되어 있다면, 결과 의사-배열의 각 변수는 지역 변수입니다. (그 함수의 매개변수 중 하나가 건네질지라도 마찬가지입니다 -- 그 매개변수가 ByRef일지라도 -- 왜냐하면 매개변수는 지역 변수와 비슷하기 때문입니다). 역으로, 첫 원소가 global로 선언되었다면, 전역 배열이 생성됩니다. 그렇지만, 아래의 흔한 혼란의 근원이 이 경우에도 적용되니다. StringSplit의 첫 원소는 ArrayName0입니다. WinGet List와 같이 다른 배열-생성 명령어에 대하여, 첫 번째 원소는 ArrayName입니다 (즉, 숫자가 없습니다). [v1.1.27+]: When force-local mode is in effect, these commands follow rules consistent with normal variable references; that is, any pseudo-array element not declared as global will be local even if other elements are declared global.
Within a function (unless force-local mode is in effect), any dynamic variable reference such as Array%i%
always resolves to a local variable unless no variable of that name exists, in which case a global is used if it exists. 아예 존재하지 않으면 새로 생성될 필요가 있습니다. 지역 변수로 생성됩니다. 단, 전역-간주 모드가 켜 있다면 전역 변수로 생성됩니다. 결과적으로, 함수는 (Array%i% := A_Index
과 같은 수단을 사용하여) 수동으로 전역 배열을 만들 수 있습니다. 물론 전역-간주 함수로 선언되어 있어야 합니다.
흔한 혼란의 근원: 변수를 동적으로 참조했는데 존재하지 않으면 스크립트가 기동하는 순간 그 변수가 생성됩니다. 예를 들어, 함수 밖에서 사용될 때, MsgBox %Array1%
는 스크립트가 기동하는 순간 Array1을 전역변수로 생성합니다. 반대로, 함수 안에서 사용될 때, MsgBox %Array1%
는 스크립트가 기동하는 순간 (전역-간주 모드가 아닌 한), Array와 Array0이 전역 변수로 선언되어 있다고 할지라도, Array1을 지역 변수중 하나로 생성합니다.
[v1.0.47.06+]: 함수는 (내장 함수도 역시) 퍼센트 사인을 통하여 동적으로 호출할 수 있습니다. 예를 들어, %Var%(x, "fox")
는 이름이 Var 안에 들어 있는 함수를 호출합니다. 비슷하게, Func%A_Index%()
는 A_Index의 현재 값에 따라서 Func1() 또는 Func2(), 등등을 호출합니다.
[v1.1.07.00+]: Var in %Var%()
can contain a function name or a function object. 해당 함수가 존재하지 않으면, 기본 베이스 객체의 __Call 메타-함수가 대신에 요청됩니다.
아래의 이유 중 하나 때문에 함수를 호출할 수 없다면, 그 호출을 담고 있는 표현식의 평가가 조용히 그리고 너무 빨리 끝나므로, 일관성 없는 결과를 도출할 수 있습니다:
If IsFunc(VarContainingFuncName)
를 사용하면 피할 수 있습니다. 내장 함수를 제외하고, 호출된 함수의 정의는 반드시 명시적으로 스크립트에 존재해야 합니다. 비-동적으로 라이브러리 함수를 호출하거나 #Include와 같은 수단을 사용합니다.마지막으로, 함수를 동적으로 호출하면 정상 호출보다 약간 더 느립니다. 왜냐하면 정상 호출은 스크립트가 실행을 하기 전에 결정(검색 완료)되기 때문입니다.
AND, OR, 그리고 삼진 연산자가 표현식 안에 사용될 때, 단축 회로 평가로 수행성을 개선합니다 (함수 호출이 존재하는가 여부에 상관없이). 단축 회로 평가는 최종 결과에 영향을 미칠 수 없는 부분을 평가하지 않습니다. 개념을 보여주기 위해, 다음 예제를 연구해 보겠습니다:
if (ColorName != "" AND not FindColor(ColorName)) MsgBox %ColorName%을 발견할 수 없습니다.
위의 예제에서, FindColor() 함수는 ColorName 변수가 비어있지 않는 한, 절대 호출되지 않습니다. 이 때문에 AND의 왼쪽이 false가 되고, 그의 오른쪽 만으로는 true라는 최종 결과를 생산할 가능성이 전혀 없기 때문입니다.
이 행위 때문에, 그 함수가 AND나 OR의 오른쪽에 호출되더라도, 함수가 생산하는 부작용이 (전역 변수의 내용을 변경하는 것과 같은) 절대로 일어나지 않을 것이라는 사실을 깨닫는 것이 중요합니다.
또 주목할 것은 단축-회로 평가가 내포된 AND와 OR에 단계적으로 적용된다는 것입니다. 예를 들어, 다음 표현식에서, ColorName이 비어 있으면 오직 왼쪽의 평가만 일어납니다. 왜냐하면 왼쪽 만으로 최종 정답을 확실하게 결정하기에 충분하기 때문입니다:
if (ColorName = "" OR FindColor(ColorName, Region1) OR FindColor(ColorName, Region2)) break ; 더 이상 검색 것이 없습니다. 일치한 것이 없습니다.
위의 예제에서 보여주는 바와 같이, 비싼 (시간이-드는) 함수라면 일반적으로 AND나 OR의 오른쪽에서 호출해야 수행성능이 개선됩니다. 이 테크닉을 사용하면 또 그의 매개변수 중 하나에 부적절한 값이, 예를 들어 빈 문자열이 건네질 때, 함수가 호출되지 못하도록 만들 수 있습니다.
[v1.0.46+]: 삼진 조건 연산자 (?:)도 단축 평가를 합니다. 필요 없는 분기는 평가하지 않습니다.
함수에 다른 함수의 정의는 담을 수 없지만, 서브루틴은 담을 수 있습니다. 다른 서브루틴과 마찬가지로 Gosub로 기동하고 Return으로 반환됩니다 (이 경우 Return은 Gosub에 속하지 함수에 속하지 않습니다).
알려진 한계: 현재, 각 서브루틴의 이름(라벨)은 전체 스크립트 안에서 유일하게 식별할 수 있어야 합니다. 프로그램은 라벨이 중복되어 있으면 기동할 때 여러분에게 고지할 것입니다.
함수가 Gosub를 사용해 (함수의 괄호 밖에 존재하는) 공개 서브루틴으로 점프해 가면, 바깥의 모든 변수는 전역 변수이고 서브루틴이 돌아올 때까지 함수 자신의 지역 변수에는 접근할 수 없습니다. 그렇지만, A_ThisFunc는 여전히 함수의 이름을 담고 있을 것입니다.
Goto로는 함수 안에서 밖으로 점프해 갈 수 없지만, 함수는 외부/공개 서브루틴으로 Gosub할 수 있으며 거기부터 Goto를 사용하면 됩니다.
Goto의 사용은 일반적으로 권장하지 않지만, 함수 안에서 또다른 위치로 점프하는데 사용할 수 있습니다. 이렇게 하면 복잡한 함수를 간략하게 만드는 데 도움이 될 수 있습니다. 반환 지점이 수 없이 많고, 그 모두가 돌아오기 전에 깨끗하게 청소해야 할 경우 유용합니다.
함수는 외부적으로-호출되는 서브루틴을 담을 수 있습니다. 예를 들어 타이머, GUI g-labels, 그리고 메뉴 항목이 그것입니다. 일반적으로 별도의 파일에 싸 넣고 #Include와 함께 사용합니다. 이렇게 하면 스크립트의 자동-실행 섹션 때문에 서로 간섭하는 일을 막을 수 있습니다. 그렇지만, 다음 한계가 적용됩니다:
다음 실행 흐름이 함수 안에서 Return을 만나기 전에 먼저 닫는 괄호에 도달하면, 그 함수는 끝나고 빈 값을 호출자에게 돌려줍니다 (빈 문자열). 빈 값은 또 함수가 명시적으로 Return의 매개변수를 생략할 때에도 반환됩니다.
함수가 Exit 명령어를 사용하여 현재 쓰레드를 종료하면, 그의 호출자는 반환 값을 전혀 받지 못합니다. 예를 들어, 다음 서술문 Var := Add(2, 3)
는 가Add()
종료하면 Var
를 그대로 둘 것입니다. 함수가 실행시간 에러를 일으켜도 같은 일이 일어납니다. 예를 들어 (UseErrorLevel가 켜져 있지 않을 때) 존재하지 않는 파일을 실행하면 같은 일이 일어납니다.
함수는 기억하기 쉬운 값을 추가로 건네기 위한 목적으로 ErrorLevel의 값을 변경할 수 있습니다.
함수를 하나 이상이 빈 값으로 호출하려면 (빈 문자열), 다음 예제와 같이 빈 따옴표 쌍을 사용합니다: FindColor(ColorName, "")
.
함수를 호출하면 새로운 쓰레드가 시작하므로, 함수가 SendMode와 SetTitleMatchMode와 같은 설정에 가한 변경은 모두 그의 호출자에게도 영향을 미칠 것입니다.
함수의 호출자는 거기에 존재하지 않은 값 또는 배열을 건넬 수 있습니다. 함수가 상응하는 매개변수를 ByRef라고 기대할 경우에 유용합니다. 예를 들어, GetNextLine(BlankArray%i%)
를 호출하면 자동으로 BlankArray%i%
변수가 생성됩니다 (호출자가 함수 안에 있는가 그리고 그 함수에 전역-간주 모드가 켜져 있는가에 따라 지역 변수 또는 전역 변수로 생성됩니다).
함수 안에서 사용될 때, ListVars는 함수의 지역 변수들을 그의 내용과 함께 보여줍니다. 이는 스크립트 디버깅에 도움이 됩니다.
복잡한 함수는 특별한 변수에 구별되는 접두사를 부여하면 더 읽기 쉽고 관리하기 좋다는 사실을 눈치채셨을 것입니다. 예를 들어, 함수의 매개변수 리스트에서 각 매개변수의 이름을 앞에 "p" 또는 "p_"를 두어 지으면 한 눈에 그의 특수한 본성을 쉽게 구별할 수 있습니다. 특히 함수에 수 십개의 지역 변수가 들어 있는데 전부 주의를 기울여 신경을 써야할 때 유용합니다. 비슷하게, 접두사 "r"이나 "r_"은 ByRef 매개변수에 사용하면 좋고, "s"나 "s_"는 정적 변수에 사용할 수 있습니다.
One True Brace (OTB) 스타일을 선택적으로 함수를 정의하는 데 사용할 수 있습니다. 예를 들어:
Add(x, y) { return x + y }
#Include 지시어를 사용하면 (스크립트의 상단에도 가능) 함수를 외부 파일로부터 적재할 수 있습니다.
설명: 스크립트의 실행 흐름이 함수 정의를 만다면, (순간적으로) 그것을 건너 뛰고 함수의 닫는 괄호 다음 줄부터 실행을 재개합니다. 결과적으로 실행은 위쪽에 있는 함수로 들어갈 수 없으며, 스크립트 최상단에 하나 이상의 함수가 존재하더라도 자동-실행 섹션에 영향을 미치지 않습니다.
스크립트는 외부 파일에 있는 함수를 호출할 수 있습니다. #Include를 사용할 필요가 없습니다. 그러려면 함수와 같은 이름의 파일이 다음 라이브러리 디렉토리 중 하나에 존재해야 합니다:
%A_ScriptDir%\Lib\ ; 지역 라이브러리 - 필수 [AHK_L 42+].
%A_MyDocuments%\AutoHotkey\Lib\ ; 사용자 라이브러리.
directory-of-the-currently-running-AutoHotkey.exe\Lib\ ; 표준 라이브러리.
예를 들어, 스크립트가 존재하지 않는 함수 MyFunc()
를 호출하면, 프로그램은 사용자 라이브러리에서 "MyFunc.ahk"라른 이름의 파일을 찾습니다. 발견하지 못하면, 표준 라이브러리에서 찾습니다. 여전히 발견하지 못하면 그리고 함수의 이름에 밑줄이 포함되어 있다면 (예, MyPrefix_MyFunc
), 프로그램은 두 라이브러리를 모두 뒤져 MyPrefix.ahk
라는 이름의 파일을 찾고 있다면 그것을 적재합니다. 이렇게 하면 MyPrefix.ahk
에 함수 MyPrefix_MyFunc
를 다음을 수있고 이름이 MyPrefix_
로 시작하는 기타 함수들을 담을 수 있습니다.
[AHK_L 42+]: 지역 라이브러리가 지원됩니다. 먼저 지역 라이브러리를 검색한 다음에 사용자 라이브러리와 표준 라이브러리를 차례로 검색합니다.
MyFunc()
와 같이 직접 호출 해야만 라이브러리가 자동-포함됩니다. 함수가 예를 들어 타이머나 구이 이벤트 같이, 동적 또는 간접적으로 호출될 때만, 명시적으로 라이브러리를 스크립트에 포함시켜야 합니다. 예를 들어: #Include <MyFunc>
라이브러리 파일은 일반적으로 그의 파일 이름으로 오직 하나의 함수만 담고 있지만, 사적으로 자신만 호출할 함수나 서브루틴을 담을 수도 있습니다. 그렇지만, 그런 함수는 이름이 구별되어야 합니다. 왜냐하면 그것들은 전역 이름공간 안에 여전히 존재할 것이기 때문입니다; 즉, 그것들은 스크립트 어디에서나 호출될 수 있습니다.
라이브러리 파일이 #Include를 사용하면, #Include를 위한 작업 디렉토리는 그 라이브러리 파일의 디렉토리입니다. 이를 이용하면 해당 함수와 관련 함수들이 들어 있는 더 큰 라이브러리 파일로 방향전환을 할 수 있습니다.
스크립트 컴파일러 (ahk2exe)도 라이브러리 함수를 지원합니다. 그렇지만, AutoHotkey.exe 사본이 위의 컴파일러 디렉토리에 존재해야 합니다 (보통 그럴 것입니다). AutoHotkey.exe가 없어도, 컴파일러는 여전히 작동하지만, 라이브러리 함수는 자동으로 포함되지 않습니다.
라이브러리로부터 포함된 함수들은 다른 함수와 똑같이 수행됩니다. 왜냐하면 스크립트가 실행되기 전에 미리-적재되기 때문입니다.
내장 함수의 매개변수 리스트 끝에 선택적인 매개변수는 완전히 생략해도 좋습니다. 예를 들어, WinExist("Untitled - Notepad")
는 유효합니다. 왜냐하면 그의 다른 세 매개변수가 빈 것으로 간주되기 때문입니다.
내장 함수는 스크립트가 자신의 함수를 같은 이름으로 정의하면 오버라이드됩니다. 예를 들어, 스크립트는 자신만의 맞춤 WinExist() 함수를 가질 수 있습니다. 표준 함수 대신에 이 함수가 호출됩니다. 그렇지만, 그렇게 되면 스크립트는 원래 함수를 호출할 방법이 없어져 버립니다.
DLL 파일에 거주하는 외부 함수는 DllCall()으로 호출합니다.
To get more details about a particular built-in function below, simply click on its name.
함수 | 설명 |
---|---|
FileExist | Checks for the existence of a file or folder and returns its attributes. |
GetKeyState | Returns true (1) if the specified key is down and false (0) if it is up. |
InStr | 왼쪽이나 오른쪽으로부터 주어진 문자열이 나타나는지 검색합니다. |
RegExMatch | 문자열 안에서 패턴 (정규 표현식)에 부합하는 것들을 찾습니다. |
RegExReplace | 문자열 안에서 패턴 (정규 표현식)에 부합하는 것들을 교체합니다. |
StrLen | 문자열에 들은 문자의 갯수를 열람합니다. |
StrReplace | Replaces occurrences of the specified substring with a new string. |
StrSplit | 문자열을 지정된 가름자를 사용하여 부분 문자열 배열로 가릅니다. |
SubStr | 문자열에서 지정된 위치로부터 하나 이상이 문자를 열람합니다. |
WinActive | Checks if the specified window is active and returns its unique ID (HWND). |
WinExist | Checks if the specified window exists and returns the unique ID (HWND) of the first matching window. |
함수 | 설명 |
---|---|
Asc | Returns the numeric value of the first byte or UTF-16 code unit in the specified string. |
Chr | Returns the string (usually a single character) corresponding to the character code indicated by the specified number. |
DllCall | 표준 Windows API 함수 같이, DLL안의 함수를 호출합니다. |
Exception | Creates an object which can be used to throw a custom exception. |
FileOpen | Opens a file to read specific content from it and/or to write new content into it. |
Format | 가변 개수의 입력 값을 형식 문자열에 맞추어 포맷합니다. |
Func | Retrieves a reference to the specified function. |
GetKeyName/VK/SC | 한 키의 스캔 코드나 가상 코드 또는 이름/텍스트를 열람합니다. |
Hotstring | Creates, modifies, enables, or disables a hotstring while the script is running. |
IL_XXX | Functions to add icons/pictures to, create or delete ImageLists used by ListView or TreeView controls. |
InputHook | Creates an object which can be used to collect or intercept keyboard input. |
IsByRef | Returns a non-zero number if the specified ByRef parameter was supplied with a variable. |
IsFunc | Returns a non-zero number if the specified function exists in the script. |
IsLabel | Returns a non-zero number if the specified label exists in the script. |
IsObject | Returns a non-zero number if the specified value is an object. |
IsSet | Returns a non-zero number if the specified variable has been assigned a value. |
LoadPicture | Loads a picture from file and returns a bitmap or icon handle. |
LV_XXX | Functions to add, insert, modify or delete ListView rows/colums, or to get data from them. |
MenuGetHandle | Retrieves the Win32 menu handle of a menu. |
MenuGetName | Retrieves the name of a menu given a handle to its underlying Win32 menu. |
NumGet | 지정된 주소+오프셋에 저장된 이진 숫자를 열람합니다. |
NumPut | 지정된 주소-오프셋에 이진 형식으로 숫자를 저장합니다. |
ObjAddRef / ObjRelease | 객체의 참조 횟수를 줄이거나 늘립니다. |
ObjBindMethod | 주어진 객체의 메쏘드를 호출하는 BoundFunc object를 생성합니다. |
ObjGetBase | Retrieves an object's base object. |
ObjRawGet | Retrieves a key-value pair from an object, bypassing the object's meta-functions. |
ObjRawSet | Stores or overwrites a key-value pair in an object, bypassing the object's meta-functions. |
ObjSetBase | Sets an object's base object. |
ObjXXX | Functions equivalent to the built-in methods of the Object type, such as ObjInsertAt. It is usually recommended to use the corresponding method instead. |
OnClipboardChange | 클립보드의 내용이 변경될 때마다 실행될 함수 또는 함수 객체를 등록합니다. |
OnError | Specifies a function to run automatically when an unhandled error occurs. |
OnExit | Specifies a function to run automatically when the script exits. |
OnMessage | 메시지/이벤트를 관제합니다. |
Ord | Returns the ordinal value (numeric character code) of the first character in the specified string. |
SB_XXX | Functions to add text/icons to or divide the bar of a StatusBar control. |
StrGet | Copies a string from a memory address, optionally converting it between code pages. |
StrPut | Copies a string to a memory address, optionally converting it between code pages. |
RegisterCallback | 머신-코드 주소를 생성합니다. 호출될 때 이 주소를 이용하여 스크립트 안의 함수로 호출을 방향전환 합니다. |
Trim / LTrim / RTrim | 문자열의 앞뒤로부터 문자들을 걷어냅니다. |
TV_XXX | Functions to add, modify or delete TreeView items, or to get data from them. |
VarSetCapacity | 변수의 가용 능력을 확대하거나 그의 메모리를 해제합니다. |
VerCompare | Compares two version strings. |
함수 | 설명 |
---|---|
Abs | Returns the absolute value of the specified number. |
Ceil | Returns the specified number rounded up to the nearest integer (without any .00 suffix). |
Exp | e (대략 2.71828182845905)를 N 만큼 제곱해서 돌려줍니다. |
Floor | Returns the specified number rounded down to the nearest integer (without any .00 suffix). |
Log | Returns the logarithm (base 10) of the specified number. |
Ln | Returns the natural logarithm (base e) of the specified number. |
Max / Min | Returns the highest/lowest value of one or more numbers. |
Mod | Returns the remainder of the specified dividend divided by the specified divisor. |
Round | Returns the specified number rounded to N decimal places. |
Sqrt | Returns the square root of the specified number. |
Sin / Cos / Tan | Returns the trigonometric sine/cosine/tangent of the specified number. |
ASin / ACos / ATan | Returns the arcsine/arccosine/arctangent in radians. |
함수 | 설명 |
---|---|
ComObjActive | 등록된 COM 객체를 열람합니다. |
ComObjArray | COM에 사용하기 위해 SAFEARRAY를 생성합니다. |
ComObjConnect | COM 객체의 이벤트를 주어진 접두사를 가진 함수에 연결합니다. |
ComObjCreate | COM 객체를 생성합니다. |
ComObject | 매개변수나 반환 값에 건넬 유형 있는 값을 나타내는 객체를 만듭니다. |
ComObjEnwrap / ComObjUnwrap | COM 객체를 포장하거나/풉니다. |
ComObjError | COM 에러의 고지를 켜고 끕니다. |
ComObjFlags | COM 포장 객체의 행위를 제어하는 플래그를 열람하거나 변경합니다. |
ComObjGet | COM 콤포넌트가 제공하는 객체 주소를 돌려줍니다. |
ComObjMissing | COM 메쏘드에 건넬 "missing parameter" 객체를 만듭니다. |
ComObjParameter | 값과 유형을 싸서 매개변수로 COM 메쏘드에 건넵니다. |
ComObjQuery | COM 객체에 인터페이스 또는 서비스를 질의합니다. |
ComObjType | 유형 정보를 COM 객체로부터 열람합니다. |
ComObjValue | COM 포장 객체에 저장된 값이나 포인터를 열람합니다. |
폴리에테네(Polyethene)의 명령어 함수: OutputVar가 있는 AutoHotkey 명령어에 호출 가능한 함수를 제공합니다. 이 라이브러리는 #Include를 통하여 스크립트에 포함할 수 있습니다.