Learn Go with Examples
I always wanted to spend more time learning Go. After a long break I finally got a chance to take it up seriously. The best lesson for me was to not learn it from scratch like I did with my first programming language. I learned a few basics first from the official documentation and Learn Go Programming - Golang Tutorial for Beginners. Since I'm already well experienced in writing good sized code bases in Python, I decided to dive right in and implement a project on top of Azure SDK. One big advantage of this approach was that I could learn from working examples in Azure documentation and build my knowledge over time. The second advantage was that I was building something useful right away that kept my motivation up; I wasn't building some abstract thing where I also needed to conjure a problem and solution.
This post is still a work in progress. I'll update it as I go along.
Companion git Repo
This blog post has a companion git repo: https://github.com/aikchar/learngo. There are multiple checkpoints in this post. Each checkpoint has a corresponding branch in the repo. As you follow along the post you can checkout the checkpoint branch and inspect it.
Initial Setup
The best place to start:
Incremental Learning
Some tricks I use as I learn Go, its type system, etc.
I use Visual Studio Code with the Go extension. By hovering the mouse over a function from a library, such as Azure SDK, I can click the documentation link that pops up right above it. It's a life saver.
Visual Studio Code also automatically add the import
line as soon as I start
using the function from that library. It's really neat.
When I'm unsure of the data type, I print it with fmt.Printf("%s", myvar)
.
The compiler yells at me that the data type is not a string and outputs the
real data type.
Organize Code
I'm still learning how to do this. This is what I know so far.
Figure out the "namespace" and name of the project. For example, my namespace is github.com/aikchar and name is learngo. The full name, or the import path, is github.com/aikchar/learngo. Create a directory of the same name to make things easier.
$ mkdir -p ~/repos/github.com/aikchar/learngo
I usually put my repos under ~/repos so that's what I did here. You can use whichever parent directory you prefer.
Create packages in sub-directories of the root directory. For example,
$ mkdir -p ~/repos/github.com/aikchar/learngo/mypkg1 $ mkdir -p ~/repos/github.com/aikchar/learngo/mypkg2
Create your main file, with package main
and func main()
, in the root
directory. You don't have to call it main.go but it's easier to identify.
$ touch ~/repos/github.com/aikchar/learngo/main.go
From here on assume we're always in the ~/repos/github.com/aikchar/learngo directory unless otherwise stated.
Modules
Initialize your go.mod first.
$ go mod init github.com/aikchar/learngo
More information:
Dependencies
Change to your project's directory and fetch your first dependency. In my case it was the Azure SDK. I fetched two different authentication libraries below.
$ go get github.com/Azure/azure-sdk-for-go/sdk/azidentity # Newer $ go get github.com/Azure/go-autorest/autorest/azure/auth # Older
If you already have the dependency downloaded in some other path, you can alias
the official import path with your local path. This uses the replace
keyword.
You can also vendor Azure SDK. It means that you maintain a copy of it in your own source tree. It removes the need to fetch it everytime you need to build your project on a new machine; it's always right there along with your code. It's optional so you decide if you want to do this.
$ go mod vendor
If you don't use a dependency in your code, you can remove depdencies
automatically. This can be tricky because if you previously go get
that
dependency it will be removed from go.mod. Use this carefully. Most people
use it before they commit their changes.
$ go mod tidy
Since we are not using any dependencies yet, let's remove Azure SDK. Run,
$ go mod tidy
More information:
main.go First Draft
Let's create a skeleton main.go
.
$ vim main.go package main func main(){}
Here we'll also try go fmt
for the first time. This will format our code
according to community standards.
$ go fmt
Build
Building is also easy.
$ go build
This will create a static binary with the same name as the parent directory. In my case it's learngo.
$ ls go.mod go.sum learngo main.go
Checkpoint 1
This is our first checkpoint. You can clone https://github.com/aikchar/learngo and checkout branch cp-1.
$ git clone https://github.com/aikchar/learngo.git $ git checkout -t origin/cp-1
I will not include binaries in the repo. For example, you won't see the learngo file.
Test
TBD