Like all major programming languages (yes, including Python and JavaScript), values in Go are typed. Unlike Python or JavaScript however, Go's functions and variables are also typed, and strongly so. What this means is that the following code will cause the program not to compile:
var a int
a = "Hello World"
This sort of behavior is known outside the academic world as strongly-typed. Within academic circles, strongly-typed is generally meaningless.
Go allows programmers to define their own types too:
type email string
Here, we're defining a new type email. The underlying kind of data is a string.
Why would you want to do this? Consider this function:
func emailSomeone(address, person string) { ... }
If both are string, it would be very easy to make a mistake—we might accidentally do something like this:
var address, person string
address = "John Smith"
person = "[email protected]"
emailSomeone(address, person)
In fact, you could even do this: emailSomeone(person, address) and the program would still compile correctly!
Imagine, however, if emailSomeone is defined thus:
func emailSomeone(address email, person string) {...}
Then the following will fail to compile:
var address email
var person string
person = "John Smith"
address = "[email protected]"
emailSomeone(person, address)
This is a good thing—it prevents bad things from happening. No more shall be said on this matter.
Go also allows programmers to define their own complex types:
type Record struct {
Name string
Age int
}
Here, we defined a new type called Record. It's a struct that contains two values: Name of type string and Age of type int.
What is a struct? Simply put, a struct is a data structure. The Name and Age in Record are called the fields of the struct.
A struct, if you come from Python, is equivalent to a tuple, but acts as a NamedTuple, if you are familiar with those. The closest equivalent in JavaScript is that it's an object. Likewise the closest equivalent in Java is that it's a plain old Java object. The closest equivalent in C# would be a plain old CLR object. In C++, the equivalent would be plain old data.
Note my careful use of the words closest equivalent and equivalent. The reason why I have delayed introduction to struct is because in most modern languages that the reader is likely to come from, it may have some form of Java-esque object orientation. A struct is not a class. It's just a definition of how data is arranged in the CPU. Hence the comparison with Python's tuples instead of Python's classes, or even Python's new data classes.
Given a value that is of type Record, one might want to extract its inner data. This can be done as so:
r := Record {
Name: "John Smith",
Age: 20,
}
r.Name
The snippet here showcases a few things:
- How to write a struct—kinded value—simply write the name of the type, and then fill in the fields.
- How to read the fields of a struct—the .Name syntax is used.
Throughout this book, I shall use .FIELDNAME as a notation to get the field name of a particular data structure. It is expected that the reader is able to understand which data structure I am talking about from context. Occasionally I may use a full term, like r.Name, to make it clear which fields I am talking about.