How to use variables and constants in Go

Variables are an important programming concept to master. They are symbols that represent values you use in your program.

This tutorial will cover some variable basics and best practices for using them in the Go programs you create.

Understanding variables

In technical terms, a variable is the assignment of a storage location to a value associated with a symbolic name or identifier. In computer programs, we use variable names to refer to stored values.

We can think of a variable as a label that has a name on it and you associate it with a value.

Suppose we have an integer 1032049348 and we want to store it in a variable instead of repeatedly entering a long number. To achieve this, we can use a name that is easy to remember, such as the variable i. To store a value in a variable we use the following syntax:

i := 1032049348

We can think of this variable as a label bound to a value.

The label says the variable name i and is bound to the integer value 1032049348.

The phrase i:= 1032049348 is a declaration and assignment statement, consisting of the following parts:

  • Variable name (i)
  • Short variable declaration assignment (:=)
  • The value bound to the variable name (1032049348)
  • Go inferred data type (int)

We’ll see how to set the type explicitly in the next section.

These parts form a statement that sets the variable i to the value of the integer 1032049348.

Once we set a variable equal to a value, weinitialize or create the variable. After doing this, you can use variables instead of values.

Once we set i to 1032049348, we can use i in place of an integer, so let’s print it out:

package main

import "fmt"

func main() {<!-- -->
i := 1032049348
fmt.Println(i)
}
Output1032049348

By using variables we can also perform mathematical operations quickly and easily. Using i:= 1032049348, we can subtract the integer 813 using the following syntax:

fmt.Println(i - 813)
Output1032048535

In this example, Go does the math for us, subtracting 813 from the variable i, returning the sum 1032048535.

Speaking of math, variables can be set equal to the result of a mathematical equation. You can also add two numbers and store the sum in the variable x:

x := 76 + 145

You may have noticed that this example looks a lot like algebra. Just like we use letters and other symbols to represent numbers and quantities in formulas and equations, variables are symbolic names that represent data type values. For correct Go syntax, you need to ensure that your variables are on the left side of any equation.

Let’s continue printing x:

package main

import "fmt"

func main() {<!-- -->
x := 76 + 145
fmt.Println(x)
}
Output221

Go returns the value 2212 because the variable x is set to the sum of 76 and 145. Variables can represent any data type, not just integers:

s := "Hello, World!"
f := 45.06
b := 5 > 9 // A Boolean value will return either true or false
array := [4]string{<!-- -->"item_1", "item_2", "item_3", "item_4"}
slice := []string{<!-- -->"one", "two", "three"}
m := map[string]string{<!-- -->"letter": "g", "number": "seven", "symbol": " & amp;"}

If you print any of these variables, Go will return the equivalent of that variable. Let us use the assignment statement of the stringslice data type:

package main

import "fmt"

func main() {<!-- -->
slice := []string{<!-- -->"one", "two", "three"}
fmt.Println(slice)
}
Output[one two three

We assign the slice value of []string{"one", "two", "three"} to the variable slice, and then use fmt.Println The code> function prints out this value by calling slice.

Variables work by carving out a small area of memory in your computer that receives specified values, and then associate those values with that space.

Declare variables

In Go, there are multiple ways to declare variables, and in some cases, multiple ways to declare the exact same variable and value.

We can declare a variable named i with data type int without initialization. This means we will declare a space to put the value in, but not give it an initial value:

var i int

This creates a variable declared as i with data type int.

This value can be initialized using the equal(=) operator, as shown in the following example:

var i int = 1

In Go, both declaration forms are called long variable declarations.

We can also use short variable declaration:

i := 1

In this example, we have a variable named i, and a data type of int. When we don’t specify the data type, Go will infer the data type.

With these three ways of declaring variables, the Go community has adopted the following idiom:

  • Use the long form var i int only when the variable is not initialized.
  • Use the abbreviation i:= 1 when declaring and initializing.
  • If you don’t want to have to infer your data type, but you still want to use short variable declarations, you can wrap the value into the desired type using the following syntax:
i := int64(1)

In Go, it is not considered idiom to use a lengthy form of variable declaration when initializing a value:

var i int = 1

It’s a good practice to follow how the Go community generally declares variables so that others can read your program seamlessly.

Zero value

All built-in types have a value of 0. Any variable that is assigned a value is available, even if it has never been assigned a value. We can see the following types of 0 values:

package main

import "fmt"

func main() {<!-- -->
var a int
var b string
var c float64
vardbool

fmt.Printf("var a %T = % + v\
", a, a)
fmt.Printf("var b %T = %q\
", b, b)
fmt.Printf("var c %T = % + v\
", c, c)
fmt.Printf("var d %T = % + v\
\
", d, d)
}
Outputvar a int = 0
var b string = ""
var c float64 = 0
vardbool=false

We use the %T verb in the fmt.Printf statement. This tells the function to print the data type of the variable.

In Go, since all values have 0 value, we cannot have undefined value like other languages. For example, in some languages, [boolean] can be undefined, true, or false, which allows variables There are three states. In Go, a Boolean value cannot have more than “two” states.

Named variables: rules and styles

Naming variables is very flexible, but there are some rules to remember.

  • Variable names can only be one word (no spaces).
  • Variable names can only consist of letters, numbers and underscores (_).
  • Variable names cannot start with a number.

Following these rules, let’s look at valid and invalid variable names:

Valid Invalid Why is it invalid
userName user-name Hyphens not allowed
name4 4name cannot start with a number
user $user Cannot use symbol
userName user name cannot exceed one word

Also, remember to be case-sensitive when naming variables. userName, userName, userName and userName are all completely different variables. It is best practice to avoid using similar variable names in your program to ensure that both you and your collaborators (now and in the future) use the variables correctly.

Although variables are case-sensitive, the case of the first letter of a variable has special meaning in Go. If a variable starts with an uppercase letter, the variable is accessible outside the package (or export) in which it is declared. If a variable starts with a lowercase letter, it can only be used within the package in which it is declared.

var Email string
var password string

Email starts with a capital letter and can be accessed by other packages. password begins with a lowercase letter and is only accessible within the package in which it is declared.

It’s very common in Go to use very concise (or short) variable names. If you want to choose between the variables userName and user, by convention you should choose user.

Scopes also help simplify variable names. The rule is that the smaller the scope of the variable, the smaller the variable name:

names := []string{<!-- -->"Mary", "John", "Bob", "Anna"}
for i, n := range names {<!-- -->
fmt.Printf("index: %d = %q\
", i, n)
}

We use variables in a larger scope, so we usually give it a more meaningful name to help remember its meaning in the program. However, we use the i and n variables immediately in the next line of code, and then never use them again… because of this, people reading the code won’t be confused about where the variables are uses, or their meaning.

Next, let’s cover some considerations about variable styles. The current style is to use MixedCaps or MixedCaps instead of underscores in multi-word names.

Conventional style Unconventional style Why is it unconventional
userName user_name Underscore is not normal
i index i than index Shorter
serveHTTP serveHttp The acronym should Capitalization

When it comes to style, the most important thing is to be consistent and that the team you work for buys into that style.

Reassign variables

As the word “variable” implies, we can change Go variables at any time. This means that we can associate a different value with a previously assigned variable by reassigning it. Being able to reassign is useful because throughout the course of a program we may need to accept user-generated values into already initialized variables. We may also need to modify previously defined assignments.

In large programs written by others, it is useful to be able to easily reassign variables if it is not clear which variables have been defined.

Let us assign the value of 76 to a variable i of type int, and then assign it a new value of 42:

package main

import "fmt"

func main() {<!-- -->
i := 76
fmt.Println(i)

i = 42
fmt.Println(i)
}
Output76
42

This example shows that we can first assign an integer to the variable i, and then reassign the variable i, this time to 42.

Note: When you declare andinitialize a variable, you can use :=, but when you want to simply change an already declared When specifying the value of a variable, you only need to use the equality operator (=).

Because Go is a typed language, we cannot assign one type to another type. For example, we cannot assign the value "Sammy" to a variable of type int:

i := 72
i = "Sammy"

Attempting to assign different types to each other will result in a compile-time error:

Outputcannot use "Sammy" (type string) as type int in assignment

Go does not allow us to use a variable name multiple times:

var s string
vars string
Outputs redeclared in this block

We also get compilation errors if we try to use a short variable declaration for the same variable name multiple times. This may happen accidentally, so it’s helpful to understand what the error message means:

i := 5
i := 10
Outputno new variables on left side of :=

Similar to variable declarations, thinking about variable naming can improve the readability of your program, both for you and for others.

Multiple assignments

Go also allows us to assign multiple values to multiple variables in the same line. These values can all be of different data types:

j, k, l := "shark", 2.05, 15
fmt.Println(j)
fmt.Println(k)
fmt.Println(l)
Outputshark
2.05
15

In this example, the variable j is assigned to the string "shark", and the variable k is assigned to the floating point number 2.05, the variable l is assigned to the integer 15.

This method of assigning multiple variables to multiple values in one line can reduce the number of lines of code. However, it’s important not to sacrifice readability for fewer lines of code.

Global variables and local variables

When using variables in a program, it is important to remember variable scope. The scope of a variable refers to the specific location within a given program’s code where the variable can be accessed. That is, not all variables are accessible in all parts of the program, some are global and some are local.

Global variables exist outside functions. Local variables exist within functions.

Let’s look at what global and local variables actually do:

package main

import "fmt"


var g = "global"

func printLocal() {<!-- -->
l := "local"
fmt.Println(l)
}

func main() {<!-- -->
printLocal()
fmt.Println(g)
}
Outputlocal
global

Here we use var g = "global" to create a global variable outside the function. Then we define the function printLocal(). Inside the function, a local variable named l is assigned a value and then printed. The program ends by calling printLocal(), and then printing the global variable g.

Because g is a global variable, we can reference it in printLocal(). Let’s modify the previous program:

package main

import "fmt"


var g = "global"

func printLocal() {<!-- -->
l := "local"
fmt.Println(l)
fmt.Println(g)
}

func main() {<!-- -->
printLocal()
fmt.Println(g)
}
Outputlocal
global
global

We first declare a global variable g, var g = "global". In the main function, we call the function printLocal, which declares a local variable l and prints it, fmt.Println(l ). Then, printLocal prints out the global variables g, fmt.Println(g). Even though g is not defined in printLocal, it can still be accessed because it is declared in the global scope. Finally, the main function also prints out g.

Now try calling a local variable outside the function:

package main

import "fmt"

var g = "global"

func printLocal() {<!-- -->
l := "local"
fmt.Println(l)
}

func main() {<!-- -->
fmt.Println(l)
}

Outputundefined: l

We cannot use it outside a function that assigns a local variable. If you try to do this, you will receive an undefined error when compiling.

Let’s look at another example where we use the same variable name for global and local variables:

package main

import "fmt"

varnum1 = 5

func printNumbers() {<!-- -->
num1 := 10
num2 := 7

fmt.Println(num1)
fmt.Println(num2)
}

func main() {<!-- -->
printNumbers()
fmt.Println(num1)
}
Output10
7
5

In this program, we declare the num1 variable twice. First, we declare num1 in the global scope, var num1 = 5, and then declare in the local scope of the printNumbers function num1:= 10. When we print num1 in the main program, we see that the value of 5 is printed. This is because main can only see the declaration of global variables. However, when we print out num1 from the printNumbers function, it sees the local declaration and will print out the value of 10. Even if printNumbers creates a new variable named num1 and assigns the value 10 to it, it will not affect num1 The global instance of has the value 5.

When using variables, you also need to consider which parts of your program need to access those variables; adopt global or local variables accordingly. In Go programs you’ll find that local variables are generally more common.

Constant

Constants are similar to variables except that once declared they cannot be modified. Constants are used to define values that are used multiple times in a program but cannot be changed.

For example, if we wanted to declare a tax rate for a shopping cart system, we could use a constant and then calculate the tax rate in different areas of the program. At some point in the future, if the tax rate changes, we only have to change one place in the program. If we use a variable, it is possible to accidentally change its value somewhere in the program, leading to incorrect calculations.

To declare a constant, you can use the following syntax:

const shark = "Sammy"
fmt.Println(shark)
OutputSammy

If we try to modify a constant after declaring it, we will get a compile-time error:

Outputcannot assign to shark

Constants can be untyped. This is useful when working with integer type data. If a constant is untyped, it will be explicitly converted, but a typed constant will not. Let’s see how to use constants:

package main

import "fmt"

const (
year=365
leapYear = int32(366)
)

func main() {<!-- -->
hours := 24
minutes := int32(60)
fmt.Println(hours * year)
fmt.Println(minutes * year)
fmt.Println(minutes * leapYear)
}
Output8760
21900
21960

If a type is specified when declaring a constant, it will be of this type. Here, when we declare the constant leapYear, we define it as data type int32. Therefore it is a typed constant, which means that it can only operate on the int32 data type. The year constant we declared has no type, so it is considered untyped. Therefore, you can use it with any integer data type.

When defining hours, it inferred that its type is int because we did not explicitly give it a type hours:= 24. When we declare minutes, we explicitly declare it as int32, minutes:= int32(60).

Now, let’s look at each calculation and why it works:

hours * year

In this example, hours is of type int, and years is untyped. When the program compiles, it explicitly converts years to int, which allows the multiplication operation to succeed.

minutes * year

In this example, minutes is int32 and year is untyped. When the program compiles, it explicitly converts years to int32, which allows the multiplication operation to succeed.

minutes * leapYear

In this example, minutes is an int32 and leapYear is a constant of type int32. This time the compiler doesn’t have to do anything because the two variables are already of the same type.

If we try to multiply two typed types that are incompatible, the program will not compile:

fmt.Println(hours * leapYear)
Outputinvalid operation: hours * leapYear (mismatched types int and int32)

In this example, hours is inferred to be of type int, while leapYear is explicitly declared to be of type int32. Because Go is a typed language, int and int32 are not compatible with mathematical operations. To multiply them, you need to convert 1 to int32 or int

Summary

In this tutorial, we reviewed some common use cases of variables in Go. Variables are an important part of programming, serving as symbols that represent values of data types used in the program.