Learning the Basic Syntax of Go: Data Types

Before you can get started in game development, you need to learn the syntax of our language of choice, go. In this post we’ll be covering the basics of go’s syntax. From what syntax even is, variables and data types, and how we represent them in our code. What is Syntax? If you’re anything like me, you’re probably asking what is syntax? When I first started development, I had that question myself.


Feb. 13, 2024 1421 words syntax · beginner ·

Before you can get started in game development, you need to learn the syntax of our language of choice, go. In this post we’ll be covering the basics of go’s syntax. From what syntax even is, variables and data types, and how we represent them in our code.

What is Syntax?

If you’re anything like me, you’re probably asking what is syntax? When I first started development, I had that question myself. Put simply, syntax is the rules of the language.

This is how the language looks and how the pieces work together together in building your application.

The basics

Before we can start looking at the rules of our code, we need to cover two ideas.

  1. Data Types
  2. Variables

Data Types

Go is a statically typed language. What does that even mean? First lets look at the basic types of data we can have.

Those are our basic data types.

But we can look a bit further to get a few more.

Variables

Think back to your experience with math, when they started adding x’s and y’s to your homework. Those were variables that you tried to solve for. Programming has variables, and they function somewhat like those pesky letters in your math, but they are slightly different.

A computer is composed of memory. And your program is written to manipulate that memory. A variable is a handy reference to that memory. Which, contains the data that you chose the variable to hold.

So, if you create a variable that holds an int, then it will always hold an int. If you have a variable that holds a string, it will always hold a string. And the go compiler will help enforce this rule.

Variable Declarations

We just got done talking about data types and variables. Let’s look at how we would use them inside of our go code. We’ll work off of our previous post, with a basic go program.

Before we look at the code itself, it is important to be aware that there are two main ways to declare a variable in go.

  1. Explicit declaration
  2. Implicit declaration We’ll talk about them after we see them.
package main

func main() {
	// Explicit declaration
	var name string
	name = "John Doe"

	// Implicit declaration
	email := "john.doe@example.com"
}

If you look at those two declarations, you’ll notice that the first (or explicit declaration) states the type the variable is, then it sets a value to the newly created variable.

The second declaration, just has the variable name, and assigns it a variable right off.

You’ll notice an equals = sign. In this case though, we will not refer to it as an equals sign, but an assigns operator. That is, we’re assigning the variable a value. (We’ll have equality checks later, that is why it is important to distinguish between the two).

Let’s look at that second (implicit) declaration. There are two things here.

  1. We didn’t give it a type, the compiler inferred the data type, because there is a string on the right hand side of the variable.
  2. We didn’t use the assign operator itself, we used a := operator. That is the syntax for an implicit declaration. Often called the walrus operator. Turn your head, and it looks like a walrus.

We did this with strings, but we can also do it with our other types as well.

package main

func main() {
	count := 100 // Integer
	distance := 45.32 // float

	isValid := false // bool
}

One more thing

In other languages, if you didn’t assign a value and try to use your variable, you could end up with problems. As the variable would point at something in memory, that would just be garbage data. This could cause weird errors in your programs. Hence the term, garbage in garbage out.

Go has a remedy for this, which has both pros and cons, but mostly pros. Go operates on default values, so if you declare a variable the explicit way, without then assigning it a value, your variable will end up with a default value.

Advanced data types

Now that you know the basic data types, we can start showing what the other types can do for us.

A slice (not a slice of fruit)

We’ll be using lists of data extensively in our programs. But first we need to understand what a list of data even is. A list is useful, for when we don’t need to really disambiguate the data that we have.

There are two main list types in go. But we’ll really only be working with the later, as it is a dynamic version of the first.

These are:

  1. Arrays
  2. Slices

A slice holds a list of our data, that we can loop/iterate over, and interact with. Let’s look at declaring a slice.

package main

func main() {
	names := []string{"John Doe", "Jane Doe", "Ned"} // An implicity declared slice of strings
}

This is a declaration of a slice. First we gave it a name (on the left side). Then we gave it a type (on the right side), []string. Followed by some {} (curly braces), with the data added. This is one of those things that might not make sense why, but as we get in developing our game, we’ll have a better contextual understanding of using this.

We can also add to our slice.

package main

func main() {
	names := []string{"John Doe", "Jane Doe", "Ned"}

	names = append(names, "Fred")
}

Other languages may have methods on the slice type itself. But go is not an object oriented language, so we can call a built in method, append, to add data to our slice. We’ll see more examples of this as we go on.

Maps (dictionaries in other languages)

If a slice is used for when we don’t need to disambiguate our data. A map is very useful when it is important for us to lookup our data by some key.

One of the biggest places that we’ll be using maps in our game development is when we want to show an animation for a specific user state. We’ll want to pull in a animation for a given entity state. So lets talk about maps.

package main

func main() {
	animations := make(map[string][]string)

	animations["idle"] = []string{"idle/0.png", "idle/1.png", "idle/2.png"}

	animations["running"] = []string{"running/0.png", "running/1.png", "running/2.png"}
}

This shows how we create a map with a key that is a string and a value that is an array of strings. So, imagine, we have an entity that we want to draw to the screen, dependent upon the state that it is in. We can store the state, and then lookup the animation series to use with that state inside of our animations map.

...
state := idle

animationList := animations[state]
...

This shows storing a state, and then looking up the animations for the state.

Structs

We’ve talked about our basic data types above. But what happens when we want to store groups of data together? We use a struct.

package main

type Person struct {
	Name string
	Email string
	IsValid bool
}

func main() {
	person := Person {
		Name: "John Doe",
		Email: "john.doe@example.com",
		IsValid: true, // Notice the comma on the last item, this is a little go syntax gotcha
	}
}

An example above had some of these values, declared as separate variables. But now, we’ve created a person struct, type Person struct, and stored some data on this struct.

In our game development, we’ll be creating structs to hold all of our level data, our player data, and our enemy data.

Before we move on

This should provide you with the basic knowledge that you need to create and work with variables in your code. I realize that you might not even know why yet that we would have variables, but understanding that they hold data for our programs will help you as we move forward.