Declaration, assignment, types, composite literals, static programming languages, dynamic programming languages & make in the Go Programming Language ( golang )

This article is going to help you.

While we are starting with basic principles here, this article will move into many principles that a lot of people get wrong. I teach go at the college and university level, to undergraduates and graduates. I have also taught over 50,000+ students online how to use the Go programming language. I know that this article will help many people gain clarity on these important concepts.

First: I want everyone to understand the distinction between declaration and assignment.

Declaration: you are declaring a variable is of a certain type.
Assignment: you are assigning a value to a variable.

In the Go programming language, you can declare a variable is of a certain type anywhere in your code:

var x int
func main() {
x = 42
fmt.Println(x)
}

Using the short declaration operator, you can both declare and assign a value to variable at the same time — however you can only do this inside a code block (between curly braces):

func main() {
x := 42
fmt.Println(x)
}
Principle: anytime you use var to DECLARE a variable to be of a certain TYPE, and if no VALUE is ASSIGNED to that variable, then the variable will be set to its ZERO VALUE.

From the language specification for the Go programming language: ​

When storage is allocated for a variable, either through a declaration or a call of new, or when a new value is created, either through a composite literal or a call of make, and no explicit initialization is provided, the variable or value is given a default value. Each element of such a variable or value is set to the zero value for its type: false for booleans, 0 for integers, 0.0 for floats, ""for strings, and nil for pointers, functions, interfaces, slices, channels, and maps. This initialization is done recursively, so for instance each element of an array of structs will have its fields zeroed if no value is specified.

These two simple declarations are equivalent:

var i int
var i int = 0

After

type T struct { i int; f float64; next *T }
t := new(T)

the following holds:

t.i == 0
t.f == 0.0
t.next == nil

The same would also be true after

var t T
Principle: a COMPOSITE LITERAL is good for adding values to a composite data structure.

Composite data structures “compose” together different pieces of data. Composite data structures are also sometimes know as “aggregate” data structures as they “aggregate together” different pieces of data.

Examples: struct, slice, map

You can use a COMPOSITE LITERAL to add values to a COMPOSITE data structure:

type person struct {
first string
}
func main() {
xs1 := []string{"Mickey"}
fmt.Println(xs1)

m := map[string]int{"Bond":27}
fmt.Println(m)

p1 := person{
first: "james",
}
fmt.Println(p1)
}
Principle: You can use MAKE to optimize the creation of some data structures.

This article is getting long, so I am not going to cover all of the nuances of make. My trainings cover make in detail. The essential take-away for you to know is that make can help you optimize the performance of your application. Here is an example of make. With a slice, for example, you can set the LEN and CAP of the slice:

type person struct {
first string
}
func main() {
xs1 := make([]string, 0, 100)
fmt.Println(len(xs1))
fmt.Println(cap(xs1))
fmt.Println(xs1)
xs1 = append(xs1, "James")
fmt.Println(len(xs1))
fmt.Println(cap(xs1))
fmt.Println(xs1)
}

Static vs Dynamic Programming Languages

You declare a variable to be of a certain type.

A static programming language, such as Go, requires that you only assignvalues of the type which is a variable is declared to store. This is why it is called static. It is not dynamic. It is static; it doesn’t change. If I have declared a variable, x, to only hold values of type int, then this will not change. It is static. X will only hold values of type int.

In contrast, a dynamic programming language will allow you to assign values of different types to a variable. X might hold the int 42 at one point in the program, and then hold the string “43” at some other point in the program. Dynamic typing leads to difficult to solve bugs.

Static typing is your friend.

The compiler will check your code and tell you if you have done something wonky.

Static typing is your friend; the compiler is your friend.

Review+

You declare a variable to be of a certain type.

You can assign a value of a certain type to a variable declared to store that type.

In go, you can use “var” to declare a variable to be of a certain type — and you can do this anywhere in your code:

var x int

You can also use “var” anywhere in your code to declare a variable to be of a certain type and to assign a value to it:

var x int = 42

The short declaration operator can only be used in a code block — between curly braces:

func main() {
x := 42
}
Best Practice: try to only use “var” to declare a variable to be of a certain type. Avoid using “var” to assign a value. Use the short declaration operator as much as possible to declare variables. Keep the scope of your variables as narrow as possible.

When you use “var” to declare a variable, but do not assign a value to the variable, then a value is automatically assigned to the variable and that value is the zero value.

The zero value varies depending upon the type: false for booleans, 0 for integers, 0.0 for floats, "" for strings, and nil for pointers, functions, interfaces, slices, channels, and maps.

Use composite literals for slices, maps, and structs. I tell my students, “A composite literal will have the type, curly braces, and then the values.

func main() {
xs := []string{"In-n-Out", "McDonald's",}
}

See the above: []string, curly braces, values

func main() {
m := map[string]int{"Bond":32, "Moneypenny":24,}
}

See the above: map[string]int, curly braces, values

type person struct {
first string
last string
}
func main() {
p1 := person{
first: "James",
last: "Bond",
}
}

See the above: person, curly braces, values

Best Practice: Always use the field name to identify the values in a struct. Notice that the last value requires the trailing comma, so always include it!

And for the last thing to review: you can use make to optimize your program when you need a slice.

Best Practice: If you have some idea of the number of items that will be used in your slice, use make to create the data structure of the appropriate size. This will avoid the creation / destruction / creation of behind-the-scenes data structures as your slice grows in size.

I hope this article was helpful to you.

Follow me on Twitter to stay current with the Go Programming Language, web development, and insights into life.

TODD MCLEOD
Golang Champion, Web Perf Evangelist, HTML / CSS Fundamentalist, JavaScript Minimalist, Innovation Specialist, Kindness Advocate, Dad, Husband, Author, Faculty
https://twitter.com/Todd_McLeod
founder: https://www.greatercommons.com/