Golang Global Variables Explained [Beginners Tutorial]

We have already covered different aspects of using variables in golang such as variable scope and how to access variables across packages which also briefly talks about golang global variables. But in this tutorial we will make our hands dirty by deep diving into this topic further with practical examples.

 

GO Variable definition

A variable is a container pointing to  a memory location where data is stored. In Go , a variable is declared using the var keyword followed by the name of the variable, the type of the variable. The type of variable also determines the kind of operations that can be applied to the variable.

Advertisement

Syntax

var username string

 

Rules for naming variables in golang

Go variables have rules that determine how variables should be created in our programs. These rules are:

  1. A variable name consists of alphabets, digits and underscores.
  2. Variables named can not have special characters in them like $, @, #, !.
  3. Variable name can not start with a number
  4. Variable names can not be the same as Go keywords like for , int, interface, struct type etc.

 

Different types of variable scope

In Go, a variable scope is the region/area in our program where a defined variable is accessible. Therefore a variable definition can be done at the package level, function level and block level. Scoping of variable results to two main of variables in Go name:

  1. Global variable
  2. Local variable

 

1. Golang Global variables

Global variable definition (To be accessed within same package)

A global variable is a variable that has been defined outside a function. A global variable can be accessed and modified inside a function, a block of code like for loop block and anywhere else in the package. Global variables hold their values throughout the lifetime of the program.

Example

package main
 
import "fmt"
 
var username string
 
 
func main() {
   username = "John Doe"
   fmt.Println("Username is ", username)
}

Explanation

Advertisement

In the above example, we define a global variable username of type string and zero value of  “” . In the main function , we assign the username variable a new value of “John Doe”. The print statement prints the new value of the username variable.

Output

$ go run main.go
Username is  John Doe

 

Global variable definition (To be accessed across different packages)

In golang we tend to create multiple package files and compile them to have a single binary. If you have a requirement to access variable across packages then follow these thumb of rule:

  1. Declare the variable in sub-package and not in the main package. A package can be shared only if it is declared in sub-packages and not the other way around in golang
  2. Make sure the first letter of the variable is in Capital Letter i.e. Uppercase such as Mypath, Testdir etc. All other words in the variable can be upper or lowercase but the first letter must be uppercase.
  3. To access the variable, use package_name.variable_name

Here I have a sub-package where I have defined a variable Mypath:

package util

var Mypath string

func init() {
	Mypath = "/tmp"
}

Let me access this variable from main package:

package main

import (
	"fmt"
	"global-vars/util"
)

func main() {
        // Access global variable across package
	fmt.Println("The path is: " + util.Mypath)
}

Output:

$ go run main.go 
The path is: /tmp

 

Editing Global variables

The value of a global variable can be changed by any code throughout the package. For example a block of code in a loop or a function can access the global variable and change it. Please note that , in case you have multiple blocks of code changing the value of a global at the same time using goroutines , this will result in undesirable results caused by race conditions. To learn more about race conditions, read the Go Mutex Tutorial .

Example

package main
 
import "fmt"
 
var counter int
 
func main() {
   for i := 0; i < 1000; i++ {
       counter += 1
   }
   fmt.Println("Counter value is ", counter)
}

 

Explanation

In the above example, we define a global variable counter with 0 as its initial value. In the main function we loop from 0 to 1000 and after every iteration, we increase the counter value by one using counter += 1. This changes the value of the global variable , and the new value is accessible all over the package.

Output

$ go run main.go
Counter value is  1000

 

Global variable as a pointer

In the previous example, we have defined global variables that are assigned values. In this section, we learn how to define the global variable with pointer initialization. The zero value of a pointer global variable is nil. To define a pointer, add asterisk(*) before the type of the variable. Since a pointer is a memory address of where data is stored, to access the value of the pointer user the ampersand (&) operator before the pointer variable to get access to the actual value. Learn more about pointers in the Go pointer tutorial.

Advertisement

Example

package main
 
import "fmt"
 
var username *string
 
func main() {
   newName := "John doe"
   new_name := fmt.Sprintf("%s", newName)
   username = &new_name
   fmt.Println(*username)
}

Explanation

In the preceding example, we define a pointer global variable of type string. The asterisk(*) before the type of the variable, indicates pointer variable definition. In the main function, we assign the username global variable a pointer to the newName variable using username = &new_name. We then print the value of the username pointer variable by adding the asterisk operator before the username pointer variable.

Output

$ go run main.go
John doe

 

Global variable and local variable preference

A local variable is a variable defined inside a function or a block of code like a loop. Local variables have a function and a block scope. In some cases you might define a global and local variable with the same name. In this case, the local variable will be used instead of the global variable.

Example

Advertisement
package main
 
import "fmt"
 
var language string = "No language"
 
func main() {
   language := "Go language"
   fmt.Println(language)
}

Explanation

In the above example, we define two variables of type string. The global variable is assigned the value “No language” and the local variable is “Go language”. When you print the value of the language variable, the value of the local variable is printed out instead. This means a local variable will always take precedence over the global variable.

Output

$ go run main.go
No language
Go language

 

2. Local variable

A local variable is a variable declared inside a function or a block of code such as a loop. The scope of a local variable is limited to the function body and the block body. If a local variable is declared twice with the same name within a scope, a compile time error will be returned.When a block or function is done executing , the lifetime of the local variable comes to an end.

Example

package main
 
import "fmt"
 
func getUsername(firstname, lastname string) string {
   username := fmt.Sprintf("%s %s", firstname, lastname)
   return username
}
 
func main() {
   firstname, lastname := "John", "Doe"
   username := getUsername(firstname, lastname)
   fmt.Println(username)
}

Explanation

Advertisement

In the above example, we define a local variable username inside the getUsername function. The  main function can not access the username variable because its access is limited to the getUsername function only.

Output

$ go run main.go
John Doe

 

Disadvantages of Go global variables

  1. Global variables are editable, and these can result in undesired results. For example it can be challenging when the global variable is changed by another block of code unintentionally.
  2. In cases where multiple goroutines are running and changing the value of the global   variable, it will result in race conditions and to avoid this we need to add more code to prevent it , such as adding Mutex, Atomic from the sync package.
  3. Global variables are only cleaned up when explicitly told so or when the program comes to an end.
  4. Global variables have no access control and any code block can access and change it.
  5. Global variables result in tight coupling of code. This becomes a headache when you try to decouple global variables.

 

Summary

In this tutorial , we learn about Go global and local variables and their scope. We also discuss the disadvantages of using Go global variables one main disadvantage being lock of access control. There , when using variables, consider using them as constants.

 

References

https://golangr.com/scope/
https://golangdocs.com/golang-global-variables

 

Related Keywords: golang global variables across packages, golang global variable initialization, golang global variable across files, golang global variables best practices, glonang global variable as pointer, Modifying glonang global variable

 

Didn't find what you were looking for? Perform a quick search across GoLinuxCloud

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can either use the comments section or contact me form.

Thank You for your support!!

Leave a Comment

X