Language Reference - Variables

Language Reference - Variables

A variable is just a place to store data in memory so that it can be accessed quickly. Think of it as a mailbox in memory that you can put information in or take information out of. For example you might create a variable to store the number a user's response to a question, or the result to a math equation.

Each variable has a name (again, similar to a mailbox) and must start with the $ character and may only contain letters, numbers and the underscore _ character. Here are some example names:

    $Var1

    $vVariable

    $my_Variable


Note that all variable names are case insensitive: MyVariable() is the same as MyvARiAblE()

Each variable is stored as a variant.

To ease script maintenability it is proposed to use a standard variable naming convention.

Declaring Variables

Variables are declared and created with the Local and Global keywords - Dim can also be used, although this is not recommended.

Local $vVariable

Or you can declare multiple variables at once:

Global $vVariable1, $vVariable2

You can also assign a variable without declaring it first, but many prefer explicit declarations.

$vVariable = "Create and Assign"

Declaring Constants

Constants are declared and created using Const keyword and must be initialised with a value:

Const $iConst1 = 1, $iConst2 = 12

Constants can also be declared and initialized using the Enum keyword:

Enum $eConst1 = 1, $eConst2, $eConst3 ; 1, 2, 3
Enum Step 2 $eIncr0, $eIncr2, $eIncr4 ; 0, 2, 4
Enum Step *2 $eMult1, $eMult2, $eMult4 ; 1, 2, 4

Once a constant has been assigned, it cannot be changed.

Scope

A variable's scope is controlled by when and how you declare the variable. If you declare a variable at the start of your script and outside any functions it exists in the global scope and can be read or changed from anywhere in the script.

If you declare a variable inside a function it is in local scope and can only be used within that same function. Variables created inside functions are automatically destroyed when the function ends.

By default when variables are declared using Dim or assigned in a function they have local scope unless there is a global variable of the same name (in which case the global variable is reused). This can be altered by using the Local and Global keywords to declare variables and force the scope you want.

See Static for details on how to use this keyword as part of the scope declaration.

Arrays and Maps

AutoIt has 2 types of data collection variables: Arrays and Maps.

Arrays are much faster for random access and can have multiple dimensions - a dimension size is fixed at the initially declared value (although it can be altered using ReDim). Arrays are indexed using integer values referring to the order of elements and start at element[0] - elements can be extracted using the integer index or iterated by a simple For...Next loop.

Maps are better for records/dictionary type access and have a single dimension. They are indexed using either integer or string keys (integers do not refer to the order of elements) and are dynamically resized as values are added or removed. A value can only be accessed by using the original key - these keys can be iterated using the TableKeys function.

Both Arrays and Maps use similar syntax, so care is required to ensure the variable is of the correct datatype - this is determined by the first declaration line for the variable:

Using empty [ ] declares a Map:

Local $mVar[] ; A Map

Filling the [ ] with a dimension size declares an Array:

Local $aVar[3] ; An Array

Assigning element values when declaring makes the variable an Array - these three lines are functionally equivalent:

Local $vVar[3] = [1, 2, 3] ; An Array
Local $vVar[] = [1, 2, 3] ; An Array
Local $vVar = [1, 2, 3] ; An Array

Arrays

An Array is a variable containing a series of data elements. Each element in this variable can be accessed by an index number which relates to the position of the element within the Array - in AutoIt the first element of an Array is always element [0]. Arrays elements are stored in a defined order and can be sorted.

An example:

You want to store a list of names: "Jasper", "Beethoven", "Pinky" and "Fidget". You could use four separate variables to do so, but using an Array is more efficient:

Local $aArray[4]
$aArray[0] = "Jasper"
$aArray[1] = "Beethoven"
$aArray[2] = "Pinky"
$aArray[3] = "Fidget"

To access a specific value in an Array, you use the index number:

$sString = $aArray[2] ; $sString contains "Pinky"

The index number can also be substituted by another variable or an expression, so you can build complex ways to assign or access elements in an array.

The elements of an entire Array can be iterated using a For...Next loop:

; UBound returns the total number of elements - as the first is [0] the highest index is one less
For $i = 0 To UBound($aArray) - 1
    ConsoleWrite(aArray[$i] & @CRLF)
Next


Arrays can also be multidimensional, when you use multiple series of index numbers.  Think of rows and columns in a grid:

$aArray[0][0] = "Upper-Left"
$aArray[1][0] = "Lower-Left"
$aArray[0][1] = "Upper-Right"
$aArray[1][1] = "Lower-Right"

(These values are just examples)

You can use up to 64 dimensions in an Array. The total number of entries cannot be greater than 2^24 (16 777 216).

Arrays must be declared before use by defining their scope using the 'Global/Local/Static' keywords and either specifying the size and/or assigning some of the elements.

Local $aArray1[2] ; Array with 2 elements, none assigned
Local $aArray[] = [8, 4, 5, 9, 1] ; Array with 5 elements, all assigned
Local $aArray[7] = [3, 7.5, "string"] ; Array with 7 elements, only first 3 assigned

Data types in Arrays

An array element can contain any AutoIt datatype:

$aArray[0] = 1
$aArray[1] = True
$aArray[2] = "Text"
$aArray[3] = $aAnotherArray

An array stored inside another array can be accessed directly, but this method is slightly slower than accessing other datatypes:

Local $aInternal[3] = ["A", "B", "C"] ; Declare an array
Local $aContainer[1] = [$aInternal] ; Declare a container array holding the first
$sString = ($aContainer[0])[1] ; $sString holds "B"
; Note the requirement to enclose the first array element definition in ( )

Maps

A Map is a variable containing a series of data elements, each consisting of a key/value pairing. An element can only be accessed by a key, which can be either a string or an integer. However an integer key does not relate to the position of the element within the Map - these are in no defined order and cannot be sorted. String keys are, almost uniquely in AutoIt, case sensitive - "MyKey" is not the same as "mykey".

An example:

You want to store a number of variables in a collection so that you can pass them to a function as a single parameter. Using a Map allows you to use string keys to make an easily understood reference to the value contained within - such as the ControlIDs of a series of controls being indexed by their names. Note that elements can be addressed by either [] or dot notation:

Local $mControls[]
$mControls["Input"] = GUICtrlCreateInput(....)
$mControls.Combo = GUICtrlCreateCombo(...)
$mControls["Button"] = GUICtrlCreateButton(...)

To access a specific value in a Map, you use the key - again either notation can be used and need not be that used initially:

$idControlID = $mMap.Input ; Variable contains the ControlID for the Input
$idControlID = $mMap["Combo"] ; Variable contains the ControlID for the Combo

Integer keys must use the [] notation and are not the same as their string equivalent:

$mMap[3] = "Integer 3" ; These are separate keys
$mMap["3"] = "String 3"

Maps must be declared before use by defining their scope using the 'Global/Local/Static' keywords.

Local $mControls[]

Datatypes in Maps

A map element can contain any AutoIt datatype:

$mMap["Integer"] = 1
$mMap.Boolean = True
$mMap["String"] = "Text"
$mMap.Array = $aArray
$mMap["Map"] = $mAnotherMap

An internal map can be accessed directly:

Local $mInternal[] ; Declare a Map
$mInternal["Internal"] = "AutoIt3" ; Assign an element
Local $mContainer[] ; Declare a container Map
$mContainer.Bin = $mInternal ; Assign the first Map as an element
; All of these return "AutoIt3"
$sString = $mContainer["Bin"]["Internal"]
$sString = $mContainer.Bin.Internal
$sString = $mContainer["Bin"].Internal
$sString = $mContainer.Bin["Internal"]

Names of Variables

The variable naming convention used in AutoIt is based on Hungarian notation. The prefix defines the logical data type rather than the physical data type: in this way, it gives a hint as to what the variable's purpose is, or what it represents. The prefix does not encode the actual data type: this occurs during assignment. See the table below for accepted standards.

prefix covering type example
a Arrays $aArray[0]
b Booleans $bBool = True
d Binaries $dBinary = Binary("0x80000000")
e Constant variable Local Const $eEulersConstant = 2.7182818284590452
f Floating point $fFloat = 0.123
h Handles (and GUI handles) $hGUI = GUICreate("My GUI")
i Integer $iInteger = 10
id An AutoIt controlID $idButton_Ok = GUICtrlCreateButton("OK", 5, 5)
m Maps $mMap[]
n General number (no preference) $nNumber = 0
p Pointers $pRect = DllStructGetPtr($tRECT)
s Strings (chars included) $sString = "Hello world"
t Structures $tSTRUCT = DllStructCreate($tagSTRUCT)
tag Structures definition $tagDATE = "struct; word Year;word Month;word Day; endstruct"
v Variant $vData = ClipGet()

Variables are named following this schema:

dollar prefix type (lower case) [optional] subtype (lower case) var name (first letter in upper case)
$ a h Handles

Examples:

; Assign a local variable the integer 7
Local $iWeekDays = 7

; Assign a local variable the value of Pi
Local $fPi = 3.14159265358979

; Assign a local variable an array of strings
Local $asArray[7] = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun']

; Assign a local variable an array of numbers
Local $anArray[4] = [0, 0.25, 3 / 4, 12]

Variable Initialization

When initializing variables there are several points to consider. It is bad practice to hog memory by assigning data which is not immediately required. It is therefore recommended that you declare and initialize variables immediately prior to use. If you wish to assign a default value to a variable which you intend to overwrite later, then the data should be of the same (or the most logical representation of its) type and use as little memory as possible.

Examples:

; Inconsistent data types are considered bad
Local $iInteger = "0"
Local $sString = False

; Correct initialization
Local $iInteger = 0
Local $sString = ''


In the following table, recommended default values are shown for each data type. Some data types have more than one possibile default value which can be used for initialization.

Default Value covering type
Binary("") $d
"" $s, $v
0 $a, $h, $i, $id, $m, $n, $o, $p, $t, $tag, $v
0.0 $f
Null $o, $s, $v
False (or True) $b


Example:

; Declare and initialize a variable with the recommended default value
Local $vUndefined = Null ; This does not require much memory

; Some time later:
$vUndefined = 0xB0AD1CEA ; Assign an appropriate value as and when needed


To reduce bloat, multiple variables can be declared on a single line. When declaring multiple variables on the same line, it is generally recommended that you stick to declaring one data type on each line. The intention here is to make the code easier to follow and manage in a future, however the best layout will vary according to circumstance.

Example:

; Not recommended
Local $sString = "", $iInteger = 0, $asArray = ["a","b","c"] ; Mixed data types

; Recommended
Local $iLeft = 10, $iTop = 10 ; Integers
Local $idButton_Go = GUICtrlCreateButton("Go", $iLeft, $iTop) ; ControlIds
Local $idButton_Quit = GUICtrlCreateButton("Quit", 50, 10) ; ControlIds


In some languages it is essential to initialize variables on declaration, but this is not the case with AutoIt. Regarding data type, variables declared without being initialized should be considered as being undefined.

Scopes of Variables

Variables should also be named according to their scope.

Global UDF variable Global variable Local variable
$__g_iSomeVar $g_iSomeVar $iSomeVar

With this method, you will avoid unwanted re-assignments.