Initial commit
This commit is contained in:
commit
1e8d9c59f4
|
@ -0,0 +1,12 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
- The skeleton of the book is created
|
||||
- The overview/TODO list is created
|
||||
- Chapter 1 is written
|
|
@ -0,0 +1,12 @@
|
|||
Copyright (c) 2019 Christine Dodrill <me@christine.website>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
PERFORMANCE OF THIS SOFTWARE.
|
|
@ -0,0 +1,9 @@
|
|||
# GetGoing
|
||||
|
||||
A book on getting started with Go.
|
||||
|
||||
## Building
|
||||
|
||||
```console
|
||||
$ ./build.sh
|
||||
```
|
|
@ -0,0 +1,27 @@
|
|||
#!/bin/sh
|
||||
|
||||
files='
|
||||
src/title.md
|
||||
CHANGELOG.md
|
||||
src/1-hello-world.md
|
||||
src/2-data-tyes.md
|
||||
src/3-slices-maps.md
|
||||
src/4-control-structures.md
|
||||
src/5-functions.md
|
||||
src/6-structures.md
|
||||
src/7-http.md
|
||||
src/8-testing.md
|
||||
src/9-cli-app.md
|
||||
src/10-repo-hygiene.md
|
||||
src/11-go-modules.md
|
||||
src/12-wiki.md
|
||||
src/13-webapp-abstractions.md
|
||||
src/14-conclusion.md
|
||||
src/15-battlesnake.md
|
||||
src/GReeTZ.md
|
||||
src/other_work_by_the_author.md
|
||||
'
|
||||
|
||||
rev=$(git rev-parse HEAD)
|
||||
|
||||
pandoc -o getgoing
|
|
@ -0,0 +1,105 @@
|
|||
---
|
||||
sitename: "Within"
|
||||
title: "Overview"
|
||||
template: blog
|
||||
---
|
||||
|
||||
The following is my overview for what I want this book to cover. This may be
|
||||
incomplete and probably will become out of date quickly, but this is basically
|
||||
my TODO list.
|
||||
|
||||
Each top level bullet point is its own chapter/workshop. Slides will be made
|
||||
available as soon as they are created.
|
||||
|
||||
- [x] Basic getting started
|
||||
- [x] installing go
|
||||
- [x] hello world
|
||||
- [x] doing math
|
||||
- [ ] Data Types
|
||||
- [ ] Variables
|
||||
- [ ] Declaring variables
|
||||
- [ ] Assigning variables
|
||||
- [ ] Integers
|
||||
- [ ] byte, int, int32, int64
|
||||
- [ ] Implement Subtract/Multiply
|
||||
- [ ] Floating-point numbers
|
||||
- [ ] Differences between floating point numbers and integers
|
||||
- [ ] float32, float64
|
||||
- [ ] Strings
|
||||
- [ ] examples of strings
|
||||
- [ ] immutable
|
||||
- [ ] combining strings
|
||||
- [ ] Slices and maps
|
||||
- [ ] generic types (this doesn’t mean Go has user-defined generic types)
|
||||
- [ ] Slices
|
||||
- [ ] creating
|
||||
- [ ] appending
|
||||
- [ ] sorting
|
||||
- [ ] common slice types
|
||||
- [ ] Maps
|
||||
- [ ] make()
|
||||
- [ ] add value
|
||||
- [ ] delete value
|
||||
- [ ] Control structures
|
||||
- [ ] conditionals
|
||||
- [ ] if
|
||||
- [ ] switch
|
||||
- [ ] type switch
|
||||
- [ ] looping
|
||||
- [ ] conditional looping
|
||||
- [ ] C-style for loop
|
||||
- [ ] iteration
|
||||
- [ ] Functions
|
||||
- [ ] Writing functions
|
||||
- [ ] Documentation
|
||||
- [ ] Types of functions
|
||||
- [ ] Functions are data
|
||||
- [ ] Functions as arguments to functions
|
||||
- [ ] Structures
|
||||
- [ ] defining structs
|
||||
- [ ] documenting structs
|
||||
- [ ] instantiating structs
|
||||
- [ ] JSON support for structures
|
||||
- [ ] What's the deal with pointers?
|
||||
- [ ] pointers make values mutable across functions
|
||||
- [ ] HTTP operations
|
||||
- [ ] fetching data from canhazip.com
|
||||
- [ ] validating response
|
||||
- [ ] parsing response
|
||||
- [ ] printing response
|
||||
- [ ] Testing
|
||||
- [ ] making a fake server for canhazip.com
|
||||
- [ ] using it in testing
|
||||
- [ ] Command line app writing
|
||||
- [ ] Flags
|
||||
- [ ] Help
|
||||
- [ ] How to test a command line app
|
||||
- [ ] Repo hygiene
|
||||
- [ ] What should go where
|
||||
- [ ] Applying that to previous things
|
||||
- [ ] Go Modules
|
||||
- [ ] how to depend on people's code
|
||||
- [ ] best practices for releasing code
|
||||
- [ ] semantic versioning and side effects
|
||||
- [ ] add markdown support to the wiki
|
||||
- [ ] Putting it all together with a webapp
|
||||
- [ ] The Wiki example from the Go documentation
|
||||
- [ ] https://golang.org/doc/articles/wiki/
|
||||
- [ ] Updated a bit
|
||||
- [ ] Tests
|
||||
- [ ] Webapp Abstractions
|
||||
- [ ] Adding a JSON api to it
|
||||
- [ ] Making a client package
|
||||
- [ ] Tests
|
||||
- [ ] Abstracting its storage layer to a database (ql?)
|
||||
- [ ] Migrations
|
||||
- [ ] Tests
|
||||
- [ ] Dockerizing
|
||||
- [ ] Making the Dockerfile
|
||||
- [ ] Testing with Docker
|
||||
- [ ] Bonus: Introduction to Battlesnake
|
||||
- [ ] brief overview of the problem space
|
||||
- [ ] the types involved
|
||||
- [ ] tutorial on how to make a snake
|
||||
- [ ] somewhere to run it?
|
||||
|
|
@ -0,0 +1,387 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 1: Get Going"
|
||||
template: blog
|
||||
---
|
||||
|
||||
This post is the first in a series I'm creating to help people learn the
|
||||
[Go][go] programming language. It's aimed at people who understand the high
|
||||
level concepts of programming, but haven't had much practical experience with
|
||||
it.
|
||||
|
||||
[go]: https://golang.org
|
||||
|
||||
Like always, feedback is very welcome. Any feedback I get will be used to help
|
||||
make this course even better.
|
||||
|
||||
## What is Go?
|
||||
|
||||
Go is a compiled programming language made by Google. It has a lot of features
|
||||
out of the box, including:
|
||||
|
||||
* A static type system
|
||||
* Fast compile times
|
||||
* Efficient code generation
|
||||
* Parallel programming for free*
|
||||
* A strong standard library
|
||||
* Cross-compilation with ease (including webassembly)
|
||||
* and more!
|
||||
|
||||
\* You still have to write code that can avoid race conditions, more on those
|
||||
later.
|
||||
|
||||
### Why Use Go?
|
||||
|
||||
Go is a very easy to read and write programming language. Consider this snippet:
|
||||
|
||||
```go
|
||||
func Add(x int, y int) int {
|
||||
return x + y
|
||||
}
|
||||
```
|
||||
|
||||
This function wraps [integer
|
||||
addition](https://golang.org/ref/spec#Arithmetic_operators). When you call it it
|
||||
returns the sum of x and y.
|
||||
|
||||
## Installing Go
|
||||
|
||||
### Linux
|
||||
|
||||
Installing Go on Linux systems is a very distribution-specific thing. Please see
|
||||
[this tutorial on
|
||||
DigitalOcean](https://www.digitalocean.com/community/tutorials/how-to-install-go-on-ubuntu-18-04)
|
||||
for more information.
|
||||
|
||||
### macOS
|
||||
|
||||
* Go to https://golang.org/dl
|
||||
* Download the .pkg file
|
||||
* Double-click on it and go through the installer process
|
||||
|
||||
### Windows
|
||||
|
||||
* Go to https://golang.org/dl
|
||||
* Download the .msi file
|
||||
* Double-click on it and go through the installer process
|
||||
|
||||
### Next Steps
|
||||
|
||||
These next steps are needed to set up your shell for Go programs.
|
||||
|
||||
Pick a directory you want to store Go programs and downloaded source code in.
|
||||
This is called your GOPATH. This is usually the `go` folder in
|
||||
your home directory. If for some reason you want another folder for this, use
|
||||
that folder instead of `$HOME/go` below.
|
||||
|
||||
#### Linux/macOS
|
||||
|
||||
This next step is unfortunately shell-specific. To find out what shell you are
|
||||
using, run the following command in your terminal:
|
||||
|
||||
```console
|
||||
$ env | grep SHELL
|
||||
```
|
||||
|
||||
The name at the path will be the shell you are using.
|
||||
|
||||
##### bash
|
||||
|
||||
If you are using bash, add the following lines to your .bashrc (Linux) or
|
||||
.bash_profile (macOS):
|
||||
|
||||
```
|
||||
export GOPATH=$HOME/go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
```
|
||||
|
||||
Then reload the configuration by closing and re-opening your terminal.
|
||||
|
||||
##### fish
|
||||
|
||||
If you are using fish, create a file in ~/.config/fish/conf.d/go.fish with the
|
||||
following lines:
|
||||
|
||||
```
|
||||
set -gx GOPATH $HOME/go
|
||||
set -gx PATH $PATH $GOPATH/bin
|
||||
```
|
||||
|
||||
##### zsh
|
||||
|
||||
If you are using zsh, add the following lines to your .zshrc:
|
||||
|
||||
```
|
||||
export GOPATH=$HOME/go
|
||||
export PATH=$PATH:$GOPATH/bin
|
||||
```
|
||||
|
||||
#### Windows
|
||||
|
||||
Follow the instructions [here](https://github.com/golang/go/wiki/SettingGOPATH#windows).
|
||||
|
||||
## Hello, world!
|
||||
|
||||
Now that everything is installed, let's test it with the classic "Hello, world!"
|
||||
program. Create a folder in your code folder called `go_learning` and create a
|
||||
subfolder called `hello`. Open a file in there called `hello.go` in your
|
||||
favorite text editor and type in the following:
|
||||
|
||||
```go
|
||||
// Command hello is your first Go program.
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func main() {
|
||||
fmt.Println("Hello, world!")
|
||||
}
|
||||
```
|
||||
|
||||
This program prints "Hello, world!" and then immediately exits. Here's each of
|
||||
the parts in detail:
|
||||
|
||||
```go
|
||||
// Command hello is your first go program.
|
||||
package main // Every go file must be in a package.
|
||||
// Package main is used for creating executable files.
|
||||
|
||||
import "fmt" // Go doesn't implicitly import anything. You need to
|
||||
// explicitly import "fmt" for printing text to
|
||||
// standard output.
|
||||
|
||||
func main() { // func main is the entrypoint of the program, or
|
||||
// where the computer starts executing your code
|
||||
fmt.Println("Hello, world!") // This prints "Hello, world!" followed by a newline
|
||||
// to standard output.
|
||||
} // This ends the main function
|
||||
```
|
||||
|
||||
Now to run this program run the following command:
|
||||
|
||||
```console
|
||||
$ go run hello.go
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
`go run` compiles and runs the code for you, without creating a persistent binary
|
||||
file. This is a good way to run programs while you are writing them.
|
||||
|
||||
To create a binary, use `go build`:
|
||||
|
||||
```console
|
||||
$ go build hello.go
|
||||
$ ./hello
|
||||
Hello, world!
|
||||
```
|
||||
|
||||
`go build` has the compiler create a persistent binary file and puts it in the
|
||||
same directory as you are running `go` from. Go will choose the filename of the
|
||||
binary based on the name of the .go file passed to it. These binaries are
|
||||
usually static binaries, or binaries that are safe to distribute to other
|
||||
computers without having to worry about linked libraries.
|
||||
|
||||
## Go Modules
|
||||
|
||||
[Go modules](https://github.com/golang/go/wiki/Modules) are the current state of
|
||||
the art of dependency and project management for programs written in Go. We will
|
||||
cover them in much more detail in the future, but for now create a module for
|
||||
your hello command with the following command:
|
||||
|
||||
```console
|
||||
$ go mod init your-name.localhost/hello
|
||||
go: creating new go.mod: module christine-dodrill.localhost/hello
|
||||
```
|
||||
|
||||
This creates a file called go.mod that tells the compiler details about your
|
||||
project. Again, we will cover this in more detail in the future, but just know
|
||||
this exists for now.
|
||||
|
||||
## Creating Other Files
|
||||
|
||||
Go packages map to folders on the filesystem. This means that every .go file in
|
||||
the same filesystem folder must be inside the same package in order for the
|
||||
package to compile. There are some edge case exceptions to this rule, of course,
|
||||
but those will be covered later.
|
||||
|
||||
### Adding Numbers
|
||||
|
||||
Create a new file called `math.go` with the following contents:
|
||||
|
||||
```
|
||||
package main
|
||||
|
||||
// Add adds two numbers and returns the sum.
|
||||
func Add(x, y int) int {
|
||||
return x + y
|
||||
}
|
||||
```
|
||||
|
||||
This file creates a function called `Add` that adds the numbers it is given.
|
||||
This function is also documented because there's a comment immediately above it
|
||||
explaining what it does. We can view the documentation with the `go doc`
|
||||
command:
|
||||
|
||||
```console
|
||||
$ go doc -all
|
||||
Command hello is your first Go program.
|
||||
|
||||
FUNCTIONS
|
||||
|
||||
func Add(x, y int) int
|
||||
Add adds two numbers and returns the sum. This helps you understand functions.
|
||||
```
|
||||
|
||||
Go automatically keeps track of documentation comments and lets you query them
|
||||
with `go doc`. These comments should usually help explain _why_ things are the
|
||||
way they are. That helps your future self understand what is going on there.
|
||||
|
||||
### Dividing Numbers
|
||||
|
||||
Go allows functions to return multiple values. When a function returns a result
|
||||
but can also results in an error it is a common idiom to return two values: the
|
||||
result and the error.
|
||||
|
||||
Unlike Java and Python, Go does not have have Exceptions that get thrown.
|
||||
Instead, errors are regular values returned by functions.
|
||||
|
||||
We can model this idiom with integer division, where anything divided by zero is
|
||||
famously undefined.
|
||||
|
||||
Add the following to `math.go`:
|
||||
|
||||
```go
|
||||
// ErrDivideByZero is returned when Divide would divide by zero.
|
||||
var ErrDivideByZero = errors.New("divide by zero")
|
||||
|
||||
// Divide performs floating-point division and returns the result. If the right
|
||||
// hand side of Divide is zero, it returns ErrDivideByZero to avoid a panic.
|
||||
func Divide(lhs, rhs float64) (float64, error) {
|
||||
if rhs == 0 {
|
||||
return 0, ErrDivideByZero
|
||||
}
|
||||
|
||||
return lhs / rhs, nil
|
||||
}
|
||||
```
|
||||
|
||||
And add this to the top of `math.go`, just below the `package` line:
|
||||
|
||||
```go
|
||||
import "errors"
|
||||
```
|
||||
|
||||
We need to import the errors package to create the ErrDivideByZero error. This
|
||||
error will be returned when the left-hand-side of the Divide function is zero.
|
||||
|
||||
### Weaving it Together
|
||||
|
||||
Now these functions in `math.go` are usable from `hello.go`. Let's add a few
|
||||
numbers after the "Hello, world!" call.
|
||||
|
||||
```go
|
||||
var sum int = Add(2, 2)
|
||||
fmt.Println("2 + 2:", sum)
|
||||
```
|
||||
|
||||
This creates an integer variable called sum and sets it to the result of adding
|
||||
2 and 2 together. You can also create the sum variable by doing this:
|
||||
|
||||
```go
|
||||
sum := Add(2, 2)
|
||||
```
|
||||
|
||||
The `:=` operator automagically declares the variable on its left hand side with
|
||||
the value on its right hand side.
|
||||
|
||||
Now run it with `go run .`. The `.` argument tells `go run` to use the package
|
||||
in the current working directory.
|
||||
|
||||
```console
|
||||
$ go run .
|
||||
Hello, world!
|
||||
2 + 2: 4
|
||||
```
|
||||
|
||||
Let's add division. Add the following lines under the last fmt.Println call:
|
||||
|
||||
```go
|
||||
quotient, err := Divide(4, 2)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("4 / 2:", quotient)
|
||||
```
|
||||
|
||||
And run it:
|
||||
|
||||
```console
|
||||
$ go run .
|
||||
Hello, world!
|
||||
2 + 2: 4
|
||||
4 / 2: 2
|
||||
```
|
||||
|
||||
Now, what would happen if you divide something by zero? Let's find out by adding
|
||||
the following after the last fmt.Println call:
|
||||
|
||||
```go
|
||||
quotient, err = Divide(4, 0)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Println("but the quotient of 4 / 0 was:", quotient)
|
||||
```
|
||||
|
||||
The `:=` operator isn't used here because that would cause a compile error. This
|
||||
error would happen because the last `:=` already defined the variables and names
|
||||
cannot be redefined in Go.
|
||||
|
||||
Now let's run it:
|
||||
|
||||
```console
|
||||
$ go run .
|
||||
Hello, world!
|
||||
2 + 2: 4
|
||||
4 / 2: 2
|
||||
panic: divide by zero
|
||||
|
||||
goroutine 1 [running]:
|
||||
main.main()
|
||||
/Users/christine.dodrill/Code/go_learning/hello/hello.go:20 +0x26c
|
||||
exit status 2
|
||||
```
|
||||
|
||||
This panics with the error "divide by zero" because of the call on line 20.
|
||||
Let's change that panic to a println so we can see what the quotient would be:
|
||||
|
||||
```go
|
||||
quotient, err = Divide(4, 0)
|
||||
if err != nil {
|
||||
fmt.Println("got an error:", err)
|
||||
}
|
||||
fmt.Println("but the quotient of 4 / 0 was:", quotient)
|
||||
```
|
||||
|
||||
And run it:
|
||||
|
||||
```console
|
||||
$ go run .
|
||||
Hello, world!
|
||||
2 + 2: 4
|
||||
4 / 2: 2
|
||||
got an error: divide by zero
|
||||
but the quotient of 4 / 0 was: 0
|
||||
```
|
||||
|
||||
The error was caught. This lets you handle errors with any custom logic you'd
|
||||
need to write. Sometimes it could mean passing an error up to its caller,
|
||||
sometimes it could mean retrying. It really depends on the context.
|
||||
|
||||
## Conclusion
|
||||
|
||||
And that about wraps it up for Lesson 1 in Go. Next we'll be covering making a
|
||||
HTTP request and validating its response with icanhazip.com. Like I mentioned
|
||||
before, feedback on this helps a lot.
|
||||
|
||||
Thanks and be well.
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 10: Repo Hygiene"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 11: Go Modules"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 12: Putting it All Together with a Wiki"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 13: Webapp Abstractions"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: "Go Training 14: Conclusion"
|
||||
sitename: Within
|
||||
template: blog
|
||||
---
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 15: Bonus: Battlesnake"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 2: Types"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 3: Slices, Arrays and Maps"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 4: Control Structures"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 5: Functions"
|
||||
template: blog
|
||||
---
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 6: Structures"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 7: HTTP Operations"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 8: Testing"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
sitename: Within
|
||||
title: "Go Training 9: Writing a Command-line App"
|
||||
template: blog
|
||||
---
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
# GReeTZ
|
||||
|
||||
This book wouldn't have been possible without the help of the following people
|
||||
(in no particular order):
|
||||
|
||||
- Amit Malhotra
|
||||
- A. Wilcox
|
||||
- Dylan Bourque
|
||||
- Ashvita Sidharthan (TODO: check spelling)
|
||||
- Edward Muller
|
||||
- Vladimir Pouzanov
|
|
@ -0,0 +1,4 @@
|
|||
# Other Work By the Author
|
||||
|
||||
- [Christine Dodrill's Blog](https://christine.website/blog)
|
||||
- [When then Zen](https://when-then-zen.christine.website)
|
|
@ -0,0 +1,6 @@
|
|||
---
|
||||
title: Get Going
|
||||
author: Christine Dodrill
|
||||
language: en_us
|
||||
rights: 0BSD
|
||||
---
|
Loading…
Reference in New Issue