Introduction
Why do we need variables in computer programming languages? This is an age-old question. Just as we can remember that the URL for the LabEx is labex.io, computer programs also need to remember some data for their use.
The purpose of variables is to represent a piece of data. In this section, we will explore how variables are used in the Go language.
Knowledge Points:
- Variable declaration
- Variable initialization
- Variable usage
- Variable lifetime
- Constants
What is a Variable?
What is a variable? In simple terms, a variable is a container used to store and save a piece of mutable data.
In compiled languages such as Go, the type of a variable is fixed.
What Does it Mean for a Variable Type to be Fixed?
It means that a variable can only hold one type of data. In other words, the items stored in the variable container are fixed.
If a variable is used to hold fruit, it should only hold fruit. Once the container has held fruit, it cannot be used to hold cookies. This is reflected in the code as a variable cannot be assigned with two different types of data.
Variable Mutability
As the name implies, a variable's value can change, as long as the change does not exceed the range allowed by its type.
The Go language has the following rules for variables:
- The name must consist of letters, digits, and underscores.
- The variable identifier cannot start with a digit.
- The identifier cannot be a reserved keyword. Check reserved keywords
- Variable names are case-sensitive, but it is not recommended to use different capitalization to distinguish between two variables with the same name.
General Declaration Method
In the Go language, the keyword used to declare variables in the general method is var.
The form of declaration is: var identifier type, which means:
var variableName variableType.
What are the common variable types in Go?
| Keyword | Explanation |
|---|---|
int |
Integer. The most common data type, taught in primary school mathematics. |
string |
String. A string of characters wrapped in double quotes, such as: "hello,world" |
bool |
Boolean. Represents true or false, with two possible values: true or false |
Since variable types are not the focus of this section, only the three most common types are listed.
More types will be explained in the following courses.
How do we declare a variable?
Now let's declare an integer variable named a.
var a int
How to remember it? You can silently say in your mind:
Define a variable named `a`, which is of type int.
Unlike many traditional programming languages, the variable type used in Go is placed after the variable name.
This way of declaring variables makes the code easier to read from left to right and avoids the spiral reading logic of the C language. For more details, please refer to the official documentation.
What name should we give a variable?
A good variable name should clearly indicate the meaning of the variable.
When naming variables, we need to pay attention to their expressiveness and avoid using abbreviations.
Here we will briefly introduce the basic method of variable naming: Camel Case Naming Convention.
Camel case naming convention uses mixed-case letters to represent a variable. The first word is in lowercase, and the first letter of each subsequent word is capitalized.
For example: currentDate. The first word, current, is in lowercase, and the second word, Date, starts with a capital letter.
In this way, a variable that represents the current date is easily understood.
This naming convention is generally used for important and commonly used variables, while temporary variables can be simplified as long as they do not cause duplication.
Batch Declaration Method
Now let's declare three variables:
var a int // Declare an integer variable named a
var b int // Declare an integer variable named b
var c int // Declare an integer variable named c
The observant students may have noticed that all three variables, a, b, c, are of type int.
In that case, we can use a comma to connect the variable names and reduce the amount of code.
var a, b, c int // Declare three variables a, b, c as integers
But what if the three variables have different types?
var a int // Declare an integer variable named a
var b string // Declare a string variable named b
var c bool // Declare a boolean variable named c
We seem to have encountered a similar situation when importing packages. Many packages with different names need to be imported together, so we can use a similar writing method:
var (
a int
b string
c bool
)
Note that this kind of declaration behavior similar to importing packages is generally used to define global variables.
Default Initialization
In Go, all variables are given initial values when they are declared. Let's explore what the initial values of variables are!
Create a file named varExercise.go in the directory ~/project.
touch ~/project/varExercise.go
Write the following code to the file:
package main
import "fmt"
func main() {
var a int
var b string
var c bool
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
You can try running it yourself and see if it matches the table below.
go run varExercise.go
The types of initial values are summarized as follows:
| Keyword | Explanation | Initial Value |
|---|---|---|
int |
Integer | 0 |
string |
String | "" |
bool |
Boolean | false |
Standard Initialization
Since the type of a variable can be determined by its initial value, can we change the default value or an already declared variable?
var a int = 1
var b string = "labex"
var c bool = true
a = 233
b = "labex"
c = false
As shown above, we just need to add = after declaring the variable, followed by an initial value that is compatible with the variable type. If you want to change the value, just use the variable name followed by = and another value of the same type.
Modify the varExercise.go file:
package main
import "fmt"
func main() {
// Declare and initialize
var a int = 1
var b string = "labex"
var c bool = true
// Print the variables
fmt.Println("Before modification:")
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
// Modify the variables
a = 233
b = "labex"
c = false
// Print the modified variables
fmt.Println("After modification:")
fmt.Println(a)
fmt.Println(b)
fmt.Println(c)
}
After running the code, the output is as follows:
$ go run varExercise.go
Before modification:
1
labex
true
After modification:
233
labex
false
You can try running it yourself and modify the initial values.
We just mentioned that the initial value assigned to a variable must be of the same type as the variable declaration. What will happen if they are different?
For example, let's assign "labex" as the initial value to the a variable:
package main
import "fmt"
func main() {
var a int = "labex"
fmt.Println(a)
}
Run the code:
$ go run varExercise.go
## command-line-arguments
./varExercise.go:6:12: cannot use "labex" (type untyped string) as type int in assignment
As shown in the figure, we cannot assign a string type such as "labex" to a variable of type int. This is because Go is a strongly typed compiled language and cannot be compiled.
Type Declaration by Inference
Since Go can determine the type of a variable by its initial value, can we simplify the process of type declaration by eliminating the step of explicitly specifying the type?
package main
import "fmt"
func main() {
// var a int = 1
var a = 1 // Type is inferred
fmt.Println(a)
}
Now you don't even need to use the var keyword to define a variable.
This way of declaring and initializing a variable can also be combined with the batch declaration method:
a, b, c := 0
// Declare variables a, b, c as integers and assign an initial value of 0
a, b, c := 0, "", true
// Declare variables a, b, c as integer, string, and boolean, respectively
Short declaration is very convenient, but be careful that := is not an assignment operation. It is a way to declare variables and is unique to Go, used to declare and initialize local variables inside a function. The type of the variable will be automatically inferred based on the expression.
Sometimes we write the following code:
func main() {
a := 1
println(a)
a := 2
println(a)
}
The compiler will tell you that there is an error in the code because the variable a has been redeclared. However, if it is written in the following way:
func main() {
a := 1
if true {
a := 2
println(a) // Output: 2
}
println(a) // Output: 1
}
There is such an output because the a with a value of 1 above and the a with a value of 2 below are not in the same variable scope (within the same curly braces), so the compiler treats them as two different variables.
The compiler will not point out your mistake, but there will be unexpected output.
In Go, it is stipulated that:
Each statement outside a function must begin with a keyword (var, func, etc.).
Therefore, the short variable declaration can only be used to declare local variables, and cannot be used to declare global variables.
So what is a global variable and what is a local variable?
This involves the concept of variable lifetime, which will be explained in the next section.
Variable Scope
Variable scope refers to the range at which a variable in a program is effective, that is, how it can be used.
You must have noticed that if you declare a variable but do not use it, the code will not compile.
In other words, when Go is compiled, it checks whether each variable has been used, that is, whether it has been used within its scope.
We can simply divide variables into three types based on their declaration positions:
- Variables defined within a function, called local variables
- Variables defined outside a function, called global variables
- Variables defined within a function definition, called formal parameters
Local Variables
In this section, most of the variables we define are local variables:
package main
import "fmt"
func main() { // Function body
var a int = 1 // Local variable
fmt.Println(a)
}
Local variables are defined within the function body, such as a defined within the main function. The scope of variable a is limited to within the main function.
At the same time, if the variable is not used in the main function, the compiler will throw an error.
Global Variables
However, it is also possible to define a global variable.
package main
import "fmt"
var a int = 1 // Global variable
func main() { // Function body
fmt.Println(a)
}
Global variables are defined outside the function body, and their scope covers the entire program. Even if they are not called in any function, an error will not be reported by the compiler.
You can think about why global variables will not produce errors even if they are not called.
Answer
This is because the global variable may be called in another package.
Details about formal parameter variables will be explained in subsequent function-related courses.
Variable Lifetime
Birds that fly away, hide the span. Scheming rabbits die, and hounds will stew. - Records of the Grand Historian
When a variable has completed its purpose, it should be destroyed to reduce memory usage.
- Global variables: The lifetime of a global variable is consistent with the entire program runtime. When the program stops running, the global variable is cleared from memory.
- Local variables: When there is no way to access a variable, its memory space will be reclaimed.
Such a design is the key to Go's high performance and efficient use of space.
During the lifetime of a variable, it cannot be redeclared.
You can write the following in varExercise.go:
package main
import "fmt"
func main() {
var a int = 1 // Local variable, lifetime is limited to the entire main function
var a int = 2 // Redefinition
fmt.Println(a)
}
After running the code:
go run varExercise.go
You will see the following error message:
./varExercise.go:7:9: a redeclared in this block
previous declaration at ./varExercise.go:6:9
The compiler tells us that a is defined again.
Constants
Many things in life are like constants. We can perceive them but cannot change them.
If a variable will not change during the entire program runtime, then we should define it as a constant.
Constants are very similar to variables, and you can even think of them as variables with immutable values.
When declaring a constant, we only need to replace the var keyword with the const keyword.
const Pi = 3.14159 // Using type inference initialization
Create a file named constExercise.go in the directory ~/project.
touch ~/project/constExercise.go
What will happen if we try to modify a constant?
package main
import "fmt"
func main() {
const Pi = 3.14159
Pi = 2 // Error: cannot assign to Pi
fmt.Println(Pi)
}
Run the code.
$ go run constExercise.go
## command-line-arguments
./constExercise.go:7:8: cannot assign to Pi
The compiler tells us that the value of Pi cannot be reassigned.
When declaring a constant, we must provide an initial value.
And the initial value assigned to a constant must be fixed at compile time.
User-defined function return values are not considered fixed in Go.
var a int = 1
// Value is fixed, declaration is valid.
const Pi = 3.14159
// The calculated value is also fixed, the declaration is valid.
const c = 1 / Pi
// Fixed return value from built-in function is valid.
const le = len("labex")
// The return value of the user-defined function is not fixed, the declaration is invalid.
const le = getLen("labby")
// `a` is a variable value that is not fixed, the declaration is invalid.
const k = a
Whether a constant declaration is valid can be summarized in the following table:
| Declaration Type | Valid |
|---|---|
| Fixed values and fixed value expressions | Valid |
| Non-fixed values (variables) and their corresponding expressions | Invalid |
Built-in function (len()) receives a fixed value and fixed value expressions |
Valid |
| User-defined functions | Invalid |
Summary
Let's review what we learned in this lab:
- The ways to declare variables
- The ways to initialize variables
- The concept of variable lifetime
- The use of constants and whether their declarations are valid
In this lab, we have reviewed the basic usage of variables in Go, demonstrated the ways to declare and use variables in different situations, and introduced constants.



