2 |
--------------------------------------------------------------------------------
/10-testing/05-profiling/curl.sh:
--------------------------------------------------------------------------------
1 | while true; do curl http://localhost:6060/english; done
--------------------------------------------------------------------------------
/10-testing/03-caching/figure1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/10-testing/03-caching/figure1.png
--------------------------------------------------------------------------------
/10-testing/02-prediction/figure1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/10-testing/02-prediction/figure1.png
--------------------------------------------------------------------------------
/10-testing/02-prediction/figure2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/10-testing/02-prediction/figure2.png
--------------------------------------------------------------------------------
/00-slides/day1/quick/helloHTTP/helloHTTP:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/00-slides/day1/quick/helloHTTP/helloHTTP
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/example1/example1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/01-variables/example1/example1
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/example1/example1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/02-struct_types/example1/example1
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/example2/example2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/02-struct_types/example2/example2
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/exercises/exercise1/exercise1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/01-variables/exercises/exercise1/exercise1
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/exercises/template1/template1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/01-variables/exercises/template1/template1
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/advanced/example1/example1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/02-struct_types/advanced/example1/example1
--------------------------------------------------------------------------------
/assets/css/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | padding-top: 80px;
3 | }
4 |
5 | .navbar-brand img {
6 | display: inline;
7 | margin: 0 10px 0 0;
8 | height: 100%;
9 | }
10 |
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/documentation/buffered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/08-concurrency_channels/03-channels/documentation/buffered.png
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/exercises/exercise1/exercise1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/01-language_syntax/02-struct_types/exercises/exercise1/exercise1
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/documentation/parallel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/08-concurrency_channels/01-goroutines/documentation/parallel.png
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/documentation/scheduler.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/08-concurrency_channels/01-goroutines/documentation/scheduler.png
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/documentation/unbuffered.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/08-concurrency_channels/03-channels/documentation/unbuffered.png
--------------------------------------------------------------------------------
/13-http/example3/public/README:
--------------------------------------------------------------------------------
1 | Put files here for additional assets.
2 |
3 | index.html and anything in a path starting with /api/
4 | will be ignored (we're handling those in specially in routes).
5 |
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/documentation/race_condition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/astaxie/gotraining-1/HEAD/08-concurrency_channels/02-race_conditions/documentation/race_condition.png
--------------------------------------------------------------------------------
/assets/js/main.js:
--------------------------------------------------------------------------------
1 | (function() {
2 | // Initialize highligh.js
3 | hljs.initHighlightingOnLoad();
4 |
5 | // Add bootstrap classes on tables
6 | $("table").addClass("table table-bordered");
7 |
8 | })()
9 |
--------------------------------------------------------------------------------
/11-standard_library/02-encoding/exercises/exercise1/data.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name":"Bill",
4 | "email":"bill@ardanstudios.com"
5 | },
6 | {
7 | "name":"Jill",
8 | "email":"jil@yahoo.com"
9 | },
10 | {
11 | "name":"Peter",
12 | "email":"peter@gmail.com"
13 | }
14 | ]
--------------------------------------------------------------------------------
/04-packaging_exporting/example1/counters/counters.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package counters provides alert counter support.
5 | package counters
6 |
7 | // AlertCounter is an exported named type that
8 | // contains an integer counter for alerts.
9 | type AlertCounter int
10 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example2/counters/counters.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package counters provides alert counter support.
5 | package counters
6 |
7 | // alertCounter is an unexported named type that
8 | // contains an integer counter for alerts.
9 | type alertCounter int
10 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example4/animals/animals.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package animals provides support.
5 | package animals
6 |
7 | // Dog represents information about dogs.
8 | type Dog struct {
9 | Name string
10 | BarkStrength int
11 | age int
12 | }
13 |
--------------------------------------------------------------------------------
/13-http/api/models/models.go:
--------------------------------------------------------------------------------
1 | // Package models contains data structures and associated behavior
2 | package models
3 |
4 | import "gopkg.in/bluesuncorp/validator.v6"
5 |
6 | var validate *validator.Validate
7 |
8 | func init() {
9 | config := validator.Config{
10 | TagName: "validate",
11 | ValidationFuncs: validator.BakedInValidators,
12 | }
13 |
14 | validate = validator.New(config)
15 | }
16 |
--------------------------------------------------------------------------------
/00-slides/day1/quick/hello/hello.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/JdC_UYCWAR
5 |
6 | // Sample program to show off Go and check programming environment.
7 | package main
8 |
9 | import "fmt"
10 |
11 | // main is the entry point for the application.
12 | func main() {
13 | // Display Hello World.
14 | fmt.Println("你好世界")
15 | }
16 |
--------------------------------------------------------------------------------
/14-cli/01-invocation/example1/child.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | )
7 |
8 | func main() {
9 | // os.Args[0] is the program name
10 | fmt.Printf("Arguments: %q\n", os.Args)
11 |
12 | // os.Getenv returns the value part of name=value
13 | fmt.Printf("Parent Shell: %q\n", os.Getenv("SHELL"))
14 |
15 | fmt.Println("Environment:")
16 |
17 | // Environ returns a slice of "name=value" strings
18 | for _, pair := range os.Environ() {
19 | fmt.Printf("\t%q\n", pair)
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example5/animals/animals.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package animals provides support for animals.
5 | package animals
6 |
7 | // animal represents information about all animals.
8 | type animal struct {
9 | Name string
10 | Age int
11 | }
12 |
13 | // Dog represents information about dogs.
14 | type Dog struct {
15 | animal // The embedded type is unexported.
16 | BarkStrength int
17 | }
18 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example3/counters/counters.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package counters provides alert counter support.
5 | package counters
6 |
7 | // alertCounter is an unexported named type that
8 | // contains an integer counter for alerts.
9 | type alertCounter int
10 |
11 | // New creates and returns values of the unexported type alertCounter.
12 | func New(value int) alertCounter {
13 | return alertCounter(value)
14 | }
15 |
--------------------------------------------------------------------------------
/14-cli/02-streams/example1/parent.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "os/exec"
7 | )
8 |
9 | func main() {
10 | // os.Args[0] is _this_ program's name
11 | args := os.Args[1:]
12 | if len(args) < 1 {
13 | // nothing to do
14 | return
15 | }
16 |
17 | cmd := exec.Command(args[0], args[1:]...)
18 |
19 | // These streams are closed if we don't set them
20 | cmd.Stdin = os.Stdin
21 | cmd.Stdout = os.Stdout
22 | cmd.Stderr = os.Stderr
23 |
24 | err := cmd.Run()
25 | if err != nil {
26 | fmt.Println(err)
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/00-slides/day1/opening/slide4.md:
--------------------------------------------------------------------------------
1 | ## Hello World
2 |
3 | Let's make sure of local development environment is working.
4 |
5 | ### Code Samples
6 |
7 | [Hello World](../quick/hello/hello.go) ([Go Playground](http://play.golang.org/p/JdC_UYCWAR))
8 |
9 | [Hello World Web](../quick/helloHTTP/helloHTTP.go) ([Go Playground](http://play.golang.org/p/c44Q5OiX5z))
10 |
11 | #### [Previous Slide](slide3.md) | [Start Training](../../readme.md)
12 | ___
13 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/13-http/api/tests/tests.go:
--------------------------------------------------------------------------------
1 | package tests
2 |
3 | import (
4 | "io"
5 | "net/http"
6 | "net/url"
7 | )
8 |
9 | // Succeed is the Unicode codepoint for a check mark.
10 | const Succeed = "\u2713"
11 |
12 | // Failed is the Unicode codepoint for an X mark.
13 | const Failed = "\u2717"
14 |
15 | // NewRequest used to setup a request for mocking API calls with httptreemux.
16 | func NewRequest(method, path string, body io.Reader) *http.Request {
17 | r, _ := http.NewRequest(method, path, body)
18 | u, _ := url.Parse(path)
19 | r.URL = u
20 | r.RequestURI = path
21 | return r
22 | }
23 |
--------------------------------------------------------------------------------
/10-testing/01-testing/example4/example4.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample program that implements a simple web service.
5 | package main
6 |
7 | import (
8 | "log"
9 | "net/http"
10 |
11 | "github.com/gobridge/gotraining/10-testing/01-testing/example4/handlers"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | handlers.Routes()
17 |
18 | log.Println("listener : Started : Listening on: http://localhost:4000")
19 | http.ListenAndServe(":4000", nil)
20 | }
21 |
--------------------------------------------------------------------------------
/editors/sublime.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {"GOPATH":"/Users/bill/Spaces/Go/Projects"},
3 | "on_save":
4 | [{
5 | "cmd": "gs9o_open", "args": {
6 | "run": ["clear"],
7 | "focus_view": false
8 | }
9 | },
10 | {
11 | "cmd": "gs9o_open", "args": {
12 | "run": ["sh", "go build"],
13 | "focus_view": false
14 | }
15 | },
16 | {
17 | "cmd": "gs9o_open", "args": {
18 | "run": ["sh", "go vet"],
19 | "focus_view": false
20 | }
21 | },
22 | {
23 | "cmd": "gs9o_open", "args": {
24 | "run": ["golint", "."],
25 | "focus_view": false
26 | }
27 | }]
28 | }
--------------------------------------------------------------------------------
/04-packaging_exporting/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample program to show how to access an exported identifier.
5 | package main
6 |
7 | import (
8 | "fmt"
9 |
10 | "github.com/gobridge/gotraining/04-packaging_exporting/example1/counters"
11 | )
12 |
13 | // main is the entry point for the application.
14 | func main() {
15 | // Create a variable of the exported type and initialize the value to 10.
16 | counter := counters.AlertCounter(10)
17 |
18 | fmt.Printf("Counter: %d\n", counter)
19 | }
20 |
--------------------------------------------------------------------------------
/00-slides/readme.md:
--------------------------------------------------------------------------------
1 | ## Go Training Classes
2 | Please choose the class and timeframe you are taking.
3 |
4 | *Note: This material has been designed to be taught in a classroom environment. The code is well commented but missing some of the contextual concepts and ideas that will be covered in class.*
5 |
6 | #### Slides
7 |
8 | [Opening Slide Deck](day1/opening/slide1.md)
9 |
10 | #### Hardcore Go
11 |
12 | [Day One](day_1_training.md) |
13 | [Day Two](day_2_training.md) |
14 | [Day Three](day_3_training.md)
15 | ___
16 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/documentation/race_condition.md:
--------------------------------------------------------------------------------
1 | ## Scheduler - Race Conditions - Concurrency and Channels
2 |
3 | ### Diagram of the race condition from the example code.
4 |
5 | 
6 |
7 | ___
8 | [](http://www.ardanlabs.com)
9 | [](http://www.ardanstudios.com)
10 | [](http://www.goinggo.net)
11 | ___
12 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/-JBSUoux-v
5 |
6 | // Declare and make a map of integer values with a string as the key. Populate the
7 | // map with five values and iterate over the map to display the key/value pairs.
8 | package main
9 |
10 | // Add imports.
11 |
12 | // main is the entry point for the application.
13 | func main() {
14 | // Declare and make a map of integer type values.
15 |
16 | // Initialize some data into the map.
17 |
18 | // Display each key/value pair.
19 | }
20 |
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/documentation/scheduler.md:
--------------------------------------------------------------------------------
1 | ## Scheduler - Goroutines - Concurrency and Channels
2 |
3 | ### Diagram of how the scheduler works.
4 |
5 | 
6 |
7 | ### Difference between concurrency and parallelism.
8 |
9 | 
10 |
11 | ___
12 | [](http://www.ardanlabs.com)
13 | [](http://www.ardanstudios.com)
14 | [](http://www.goinggo.net)
15 | ___
16 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/documentation/channels.md:
--------------------------------------------------------------------------------
1 | ## Scheduler - Channels - Concurrency and Channels
2 |
3 | ### Diagram of how an unbuffered channel works.
4 |
5 | 
6 |
7 | ### Diagram of how a buffered channel works.
8 |
9 | 
10 |
11 | ___
12 | [](http://www.ardanlabs.com)
13 | [](http://www.ardanstudios.com)
14 | [](http://www.goinggo.net)
15 | ___
16 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/04-packaging_exporting/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample program to show how the program can access a value
5 | // of an unexported identifier from another package.
6 | package main
7 |
8 | import (
9 | "fmt"
10 |
11 | "github.com/gobridge/gotraining/04-packaging_exporting/example3/counters"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Create a variable of the unexported type using the exported
17 | // New function from the package counters.
18 | counter := counters.New(10)
19 |
20 | fmt.Printf("Counter: %d\n", counter)
21 | }
22 |
--------------------------------------------------------------------------------
/14-cli/03-flow/example1/parent.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "os/exec"
7 | )
8 |
9 | func fail(err error) {
10 | // output errors to stderr
11 | fmt.Fprintln(os.Stderr, err)
12 | // exit with non-zero status to indicate command failure
13 | os.Exit(1)
14 | }
15 |
16 | func main() {
17 | // os.Args[0] is _this_ program's name
18 | args := os.Args[1:]
19 | if len(args) < 1 {
20 | // nothing to do
21 | return
22 | }
23 |
24 | cmd := exec.Command(args[0], args[1:]...)
25 |
26 | // These streams are closed if we don't set them
27 | cmd.Stdin = os.Stdin
28 | cmd.Stdout = os.Stdout
29 | cmd.Stderr = os.Stderr
30 |
31 | err := cmd.Run()
32 | if err != nil {
33 | fail(err)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/09-concurrency_patterns/chat/main/main.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // This example is provided with help by Gabriel Aszalos.
5 |
6 | // This sample program demonstrates how to create a simple chat system.
7 | package main
8 |
9 | import (
10 | "log"
11 | "os"
12 | "os/signal"
13 |
14 | "github.com/gobridge/gotraining/09-concurrency_patterns/chat"
15 | )
16 |
17 | func main() {
18 | cr := chat.New()
19 |
20 | sigChan := make(chan os.Signal, 1)
21 | signal.Notify(sigChan, os.Interrupt)
22 | <-sigChan
23 |
24 | log.Println("Shutting Down Started")
25 | cr.Close()
26 | log.Println("Shutting Down Completed")
27 | }
28 |
--------------------------------------------------------------------------------
/01-language_syntax/04-constants/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/ExxRWe6jUz
5 |
6 | // Sample program to show how constants do have a parallel type system.
7 | package main
8 |
9 | import "fmt"
10 |
11 | const (
12 | // Max integer value on 64 bit architecture.
13 | maxInt = 9223372036854775807
14 |
15 | // Much larger value than int64.
16 | bigger = 9223372036854775808543522345
17 |
18 | // Will NOT compile
19 | // biggerInt int64 = 9223372036854775808543522345
20 | )
21 |
22 | // main is the entry point for the application.
23 | func main() {
24 | fmt.Println("Will Compile")
25 | }
26 |
--------------------------------------------------------------------------------
/10-testing/03-caching/caching_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/opI__KHj9a
5 |
6 | // go test -run=XXX -bench=.
7 |
8 | // Tests to show how why CPU caches matter.
9 | package caching
10 |
11 | import "testing"
12 |
13 | // BenchmarkRowTraverse capture the time it takes to perform
14 | // a row traversal.
15 | func BenchmarkRowTraverse(b *testing.B) {
16 | for i := 0; i < b.N; i++ {
17 | rowTraverse()
18 | }
19 | }
20 |
21 | // BenchmarkColTraverse capture the time it takes to perform
22 | // a column traversal.
23 | func BenchmarkColTraverse(b *testing.B) {
24 | for i := 0; i < b.N; i++ {
25 | colTraverse()
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example5/example5.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample program to show how to create values from exported types with
5 | // embedded unexported types.
6 | package main
7 |
8 | import (
9 | "fmt"
10 |
11 | "github.com/gobridge/gotraining/04-packaging_exporting/example5/animals"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | /// Create a value of type Dog from the animals package.
17 | dog := animals.Dog{
18 | BarkStrength: 10,
19 | }
20 |
21 | // Set the exported fields from the unexported animal inner type.
22 | dog.Name = "Chole"
23 | dog.Age = 1
24 |
25 | fmt.Printf("Dog: %#v\n", dog)
26 | }
27 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example4/example4.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample program to show how unexported fields from an exported struct
5 | // type can't be accessed directly.
6 | package main
7 |
8 | import (
9 | "fmt"
10 |
11 | "github.com/gobridge/gotraining/04-packaging_exporting/example4/animals"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Create a value of type Dog from the animals package.
17 | dog := animals.Dog{
18 | Name: "Chole",
19 | BarkStrength: 10,
20 | age: 5,
21 | }
22 |
23 | // ./example4.go:20: unknown animals.Dog field 'age' in struct literal
24 |
25 | fmt.Printf("Dog: %#v\n", dog)
26 | }
27 |
--------------------------------------------------------------------------------
/02-array_slices_maps/01-arrays/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/s4BSgxz0Y3
5 |
6 | // Sample program to show how the behavior of the for range and
7 | // how memory for an array is contiguous.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare an array of 5 strings initialized with values.
17 | five := [5]string{"Annie", "Betty", "Charley", "Doug", "Edward"}
18 |
19 | // Iterate over the array displaying the value and
20 | // address of each element.
21 | for i, v := range five {
22 | fmt.Printf("Value[%s] Address[%p] IndexAddr[%p]\n", v, &v, &five[i])
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/04-packaging_exporting/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample program to show how the program can't access an
5 | // unexported identifier from another package.
6 | package main
7 |
8 | import (
9 | "fmt"
10 |
11 | "github.com/gobridge/gotraining/04-packaging_exporting/example2/counters"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Create a variable of the unexported type and initialize the value to 10.
17 | counter := counters.alertCounter(10)
18 |
19 | // ./example2.go:17: cannot refer to unexported name counters.alertCounter
20 | // ./example2.go:17: undefined: counters.alertCounter
21 |
22 | fmt.Printf("Counter: %d\n", counter)
23 | }
24 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/02-interfaces/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/yaUWLZjidB
5 |
6 | // Sample program to show how you can't always get the address of a value.
7 | package main
8 |
9 | import "fmt"
10 |
11 | // duration is a named type with a base type of int.
12 | type duration int
13 |
14 | // format pretty-prints the duration value.
15 | func (d *duration) pretty() {
16 | fmt.Println("Duration:", *d)
17 | }
18 |
19 | // main is the entry point for the application.
20 | func main() {
21 | duration(42).pretty()
22 |
23 | // ./example3.go:21: cannot call pointer method on duration(42)
24 | // ./example3.go:21: cannot take the address of duration(42)
25 | }
26 |
--------------------------------------------------------------------------------
/13-http/example2/main.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/Qmj_C5PEs1
5 |
6 | // Sample program to show how you can use the FileServer handle with
7 | // this service as a single call to ListenAndServe.
8 | package main
9 |
10 | import "net/http"
11 |
12 | func main() {
13 | // Since the http.Handler interface is so universal and ubiquitous, you can
14 | // encapsulate some really neat pieces of functionality in a single
15 | // http.Handler. You can mount http.Handlers to routers, middleware, filters,
16 | // and other server constructs.
17 | //
18 | // In this example we will create a file server in one line of code
19 | http.ListenAndServe(":4000", http.FileServer(http.Dir(".")))
20 | }
21 |
--------------------------------------------------------------------------------
/13-http/api/middleware/request_logger.go:
--------------------------------------------------------------------------------
1 | package middleware
2 |
3 | import (
4 | "log"
5 | "time"
6 |
7 | "github.com/gobridge/gotraining/13-http/api/app"
8 | )
9 |
10 | // RequestLogger writes some information about the request to the logs in
11 | // the format: SESSIONID : (200) GET /foo -> IP ADDR (latency)
12 | func RequestLogger(h app.Handler) app.Handler {
13 | return func(c *app.Context) error {
14 | log.Printf("%v : middleware : RequestLogger : Started", c.SessionID)
15 |
16 | start := time.Now()
17 | err := h(c)
18 |
19 | log.Printf("%v : (%d) %s %s -> %s (%s)",
20 | c.SessionID,
21 | c.Status, c.Request.Method, c.Request.URL.Path,
22 | c.Request.RemoteAddr, time.Since(start),
23 | )
24 |
25 | log.Printf("%v : middleware : RequestLogger : Completed", c.SessionID)
26 |
27 | return err
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/10-testing/01-testing/example4/handlers/handlers.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package handlers provides the endpoints for the web service.
5 | package handlers
6 |
7 | import (
8 | "encoding/json"
9 | "net/http"
10 | )
11 |
12 | // Routes sets the routes for the web service.
13 | func Routes() {
14 | http.HandleFunc("/sendjson", SendJSON)
15 | }
16 |
17 | // SendJSON returns a simple JSON document.
18 | func SendJSON(rw http.ResponseWriter, r *http.Request) {
19 | u := struct {
20 | Name string
21 | Email string
22 | }{
23 | Name: "Bill",
24 | Email: "bill@ardanstudios.com",
25 | }
26 |
27 | rw.Header().Set("Content-Type", "application/json")
28 | rw.WriteHeader(200)
29 | json.NewEncoder(rw).Encode(&u)
30 | }
31 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/fWJR3Kln4Y
5 |
6 | // Sample program to show how the capacity of the slice
7 | // is not available for use.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Create a slice with a length of 5 elements.
17 | slice := make([]string, 5)
18 | slice[0] = "Apple"
19 | slice[1] = "Orange"
20 | slice[2] = "Banana"
21 | slice[3] = "Grape"
22 | slice[4] = "Plum"
23 |
24 | // You can't access an index of a slice beyond its length.
25 | slice[5] = "Runtime error"
26 |
27 | // Error: panic: runtime error: index out of range
28 |
29 | fmt.Println(slice)
30 | }
31 |
--------------------------------------------------------------------------------
/10-testing/01-testing/example4/handlers/handlers_example_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample to show how to write a basic example.
5 | package handlers_test
6 |
7 | import (
8 | "encoding/json"
9 | "fmt"
10 | "log"
11 | "net/http"
12 | "net/http/httptest"
13 | )
14 |
15 | // ExampleSendJSON provides a basic example example.
16 | func ExampleSendJSON() {
17 | r, _ := http.NewRequest("GET", "/sendjson", nil)
18 | w := httptest.NewRecorder()
19 | http.DefaultServeMux.ServeHTTP(w, r)
20 |
21 | var u struct {
22 | Name string
23 | Email string
24 | }
25 |
26 | if err := json.NewDecoder(w.Body).Decode(&u); err != nil {
27 | log.Println("ERROR:", err)
28 | }
29 |
30 | fmt.Println(u)
31 | // Output:
32 | // {Bill bill@ardanstudios.com}
33 | }
34 |
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/_xxuE1Ep6U
5 |
6 | // Sample program to show how to declare and initialize anonymous
7 | // struct types.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare a variable of an anonymous type and init
17 | // using a struct literal.
18 | e := struct {
19 | flag bool
20 | counter int16
21 | pi float32
22 | }{
23 | flag: true,
24 | counter: 10,
25 | pi: 3.141592,
26 | }
27 |
28 | // Display the values.
29 | fmt.Printf("%+v\n", e)
30 | fmt.Println("Flag", e.flag)
31 | fmt.Println("Counter", e.counter)
32 | fmt.Println("Pi", e.pi)
33 | }
34 |
--------------------------------------------------------------------------------
/07-error_handling/example5/example5.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/czXpjvWWTT
5 |
6 | // Sample program to show see if the class can find the bug.
7 | package main
8 |
9 | import (
10 | "log"
11 | )
12 |
13 | // customError is just an empty struct.
14 | type customError struct{}
15 |
16 | // Error implements the error interface.
17 | func (c *customError) Error() string {
18 | return "Find the bug."
19 | }
20 |
21 | // fail returns nil values for both return types.
22 | func fail() ([]byte, *customError) {
23 | return nil, nil
24 | }
25 |
26 | // main is the entry point for the application.
27 | func main() {
28 | var err error
29 | if _, err = fail(); err != nil {
30 | log.Fatal("Why did this fail?")
31 | }
32 |
33 | log.Println("No Error")
34 | }
35 |
--------------------------------------------------------------------------------
/01-language_syntax/04-constants/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/qG3-9yn5_6
5 |
6 | // Declare an untyped and typed constant and display their values.
7 | //
8 | // Multiply two literal constants into a typed variable and display the value.
9 | package main
10 |
11 | // Add imports.
12 |
13 | // Declare a constant named server of kind string and assign a value.
14 |
15 | // Declare a constant named port of type integer and assign a value.
16 |
17 | // main is the entry point for the application.
18 | func main() {
19 | // Display the value of both server and port.
20 |
21 | // Divide a constant of kind integer and kind floating point and
22 | // assign the result to a variable.
23 |
24 | // Display the value of the variable.
25 | }
26 |
--------------------------------------------------------------------------------
/02-array_slices_maps/01-arrays/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/LVD43cYBNS
5 |
6 | // Sample program to show how arrays of different sizes are
7 | // not of the same type.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare an array of 5 integers that is initialized
17 | // to its zero value.
18 | var five [5]int
19 |
20 | // Declare an array of 4 integers that is initialized
21 | // with some values.
22 | four := [4]int{10, 20, 30, 40}
23 |
24 | // Assign one array to the other
25 | five = four
26 |
27 | // ./example2.go:20: cannot use four (type [4]int) as type [5]int in assignment
28 |
29 | fmt.Println(four)
30 | fmt.Println(five)
31 | }
32 |
--------------------------------------------------------------------------------
/02-array_slices_maps/01-arrays/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/ggjjRPzhAB
5 |
6 | // Declare an array of 5 strings with each element initialized to its zero value.
7 | //
8 | // Declare a second array of 5 strings and initialize this array with literal string
9 | // values. Assign the second array to the first and display the results of the first array.
10 | package main
11 |
12 | // Add imports.
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare an array of 5 strings set to its zero value.
17 |
18 | // Declare an array of 5 strings and pre-populate it with names.
19 |
20 | // Assign the populated array to the array of zero values.
21 |
22 | // Iterate over the first array declared.
23 | }
24 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/nNnsK6hWdP
5 |
6 | // Sample program to show the basic concept of pass by value.
7 | package main
8 |
9 | // main is the entry point for the application.
10 | func main() {
11 | // Declare variable of type int with a value of 10.
12 | count := 10
13 |
14 | // Display the "value of" and "address of" count.
15 | println("Before:", count, &count)
16 |
17 | // Pass the "value of" the variable count.
18 | increment(count)
19 |
20 | println("After: ", count, &count)
21 | }
22 |
23 | // increment declares count as a variable whose value is
24 | // always an integer.
25 | func increment(inc int) {
26 | // Increment the "value of" inc.
27 | inc++
28 | println("Inc: ", inc, &inc)
29 | }
30 |
--------------------------------------------------------------------------------
/01-language_syntax/04-constants/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/d2gkKxEftw
5 |
6 | // Declare an untyped and typed constant and display their values.
7 | //
8 | // Multiply two literal constants into a typed variable and display the value.
9 | package main
10 |
11 | import "fmt"
12 |
13 | // server is the IP address for connecting.
14 | const server = "124.53.24.123"
15 |
16 | // port is the port to make that connection.
17 | const port int16 = 9000
18 |
19 | // main is the entry point for the application.
20 | func main() {
21 | // Display the server information.
22 | fmt.Println(server)
23 | fmt.Println(port)
24 |
25 | // Calculate the number of minutes in 5320 seconds.
26 | minutes := 5320 / 60.0
27 | fmt.Println(minutes)
28 | }
29 |
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/ItPe2EEy9X
5 |
6 | // Declare a struct type to maintain information about a user (name, email and age).
7 | // Create a value of this type, initialize with values and display each field.
8 | //
9 | // Declare and initialize an anonymous struct type with the same three fields. Display the value.
10 | package main
11 |
12 | // Add imports.
13 |
14 | // Add user type and provide comment.
15 |
16 | // main is the entry point for the application.
17 | func main() {
18 | // Declare variable of type user and init using a struct literal.
19 |
20 | // Display the field values.
21 |
22 | // Declare a variable using an anonymous struct.
23 |
24 | // Display the field values.
25 | }
26 |
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/1JmxvWLAET
5 |
6 | // Sample program to show how only types that can have
7 | // equality defined on them can be a map key.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // user defines a user in the program.
15 | type user struct {
16 | name string
17 | email string
18 | }
19 |
20 | // users define a set of users.
21 | type users []user
22 |
23 | // main is the entry point for the application.
24 | func main() {
25 | // Declare and make a map uses a slice of users as the key.
26 | u := make(map[users]int)
27 |
28 | // ./example3.go:26: invalid map key type users
29 |
30 | // Iterate over the map.
31 | for key, value := range u {
32 | fmt.Println(key, value)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/14-cli/02-streams/example2/pipeline.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "os"
6 | "os/exec"
7 | )
8 |
9 | func main() {
10 | c1 := exec.Command("df", "-h")
11 | c2 := exec.Command("sort")
12 |
13 | r, err := c1.StdoutPipe()
14 | if err != nil {
15 | fmt.Println("failed to create pipe:", err)
16 | return
17 | }
18 | defer r.Close()
19 |
20 | c1.Stdin = os.Stdin
21 | c1.Stderr = os.Stderr
22 |
23 | // the stdout of c1 feeds the stdin of c2
24 | c2.Stdin = r
25 | c2.Stdout = os.Stdout
26 | c2.Stderr = os.Stderr
27 |
28 | err = c1.Start()
29 | if err != nil {
30 | fmt.Println("process #1 failed to start:", err)
31 | }
32 |
33 | // we Wait on c1 to clean up its process entry when done
34 | // (otherwise, it'll remain as a zombie process until this process exits)
35 | defer c1.Wait()
36 |
37 | err = c2.Run()
38 | if err != nil {
39 | fmt.Println("process #2 failed:", err)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/13-http/api/routes/routes.go:
--------------------------------------------------------------------------------
1 | package routes
2 |
3 | import (
4 | "net/http"
5 |
6 | "github.com/gobridge/gotraining/13-http/api/app"
7 | "github.com/gobridge/gotraining/13-http/api/handlers"
8 | )
9 |
10 | // API returns a handler for a set of routes.
11 | func API() http.Handler {
12 | a := app.New()
13 |
14 | // Setup the file server to serve up static content such as
15 | // the index.html page.
16 | a.TreeMux.NotFoundHandler = http.FileServer(http.Dir("views")).ServeHTTP
17 |
18 | // Initialize the routes for the API binding the route to the
19 | // handler code for each specified verb.
20 | a.Handle("GET", "/v1/users", handlers.Users.List)
21 | a.Handle("POST", "/v1/users", handlers.Users.Create)
22 | a.Handle("GET", "/v1/users/:id", handlers.Users.Retrieve)
23 | a.Handle("PUT", "/v1/users/:id", handlers.Users.Update)
24 | a.Handle("DELETE", "/v1/users/:id", handlers.Users.Delete)
25 |
26 | return a
27 | }
28 |
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/hC1o26x7Q5
5 |
6 | // Sample program to show how to declare and initialize a map
7 | // using a map literal.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // user defines a user in the program.
15 | type user struct {
16 | name string
17 | email string
18 | }
19 |
20 | // main is the entry point for the application.
21 | func main() {
22 | // Declare and initialize the map with values.
23 | users := map[string]user{
24 | "Rob": user{"Roy", "Rob"},
25 | "Ford": user{"Henry", "Ford"},
26 | "Mouse": user{"Mickey", "Mouse"},
27 | "Jackson": user{"Michael", "Jackson"},
28 | }
29 |
30 | // Iterate over the map.
31 | for key, value := range users {
32 | fmt.Println(key, value)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/00-slides/day_3_training.md:
--------------------------------------------------------------------------------
1 | ## Go Training - Day 3
2 | On this day we continue go deeper into Go. We learn about concurrency patterns, testing, benchmarking, debugging, logging, encoding, io, and reflection.
3 |
4 | *Note: This material has been designed to be taught in a classroom environment. The code is well commented but missing some of the contextual concepts and ideas that will be covered in class.*
5 |
6 | #### Concurrency Patterns
7 | [Concurrency Patterns](../09-concurrency_patterns/readme.md)
8 |
9 | #### Testing, Prediction, Godebug and Profiling
10 | [Testing and Debugging](../10-testing/readme.md)
11 |
12 | #### Logging, Encoding and IO
13 | [Standard Library](../11-standard_library/readme.md)
14 |
15 | #### Reflection
16 | [Reflection](../12-reflection/readme.md)
17 |
18 | #### HTTP
19 | [HTTP](../13-http/readme.md)
20 | ___
21 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/10-testing/readme.md:
--------------------------------------------------------------------------------
1 | ## Testing and Debugging
2 |
3 | Go has support for both testing and debugging. This includes profiling and benchmarking Go programs.
4 |
5 | ## Package Review
6 |
7 | [Testing](../10-testing/01-testing/readme.md)
8 |
9 | [Prediction](../10-testing/02-prediction/readme.md)
10 |
11 | [Caching](../10-testing/03-caching/readme.md)
12 |
13 | [Godebug](../10-testing/04-godebug/readme.md)
14 |
15 | [Profiling](../10-testing/05-profiling/readme.md)
16 |
17 | ## Exercises
18 |
19 | ### Exercise 1
20 | Write three benchmark tests for converting an integer into a string. First use the fmt.Sprintf function, then the strconv.FormatInt function and finally the strconv.Itoa. Identify which function performs the best.
21 |
22 | [Template](exercises/template1/bench_test.go) |
23 | [Answer](exercises/exercise1/bench_test.go)
24 | ___
25 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/advanced/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/pQsoB02pDl
5 |
6 | // Sample program to show how to compose maps of maps.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | )
12 |
13 | // Data defines a key/value store.
14 | type Data map[string]string
15 |
16 | // main is the entry point for the application.
17 | func main() {
18 | // Declare and make a map of Data type values.
19 | users := make(map[string]Data)
20 |
21 | // Initialize some data into our map of maps.
22 | users["clients"] = Data{"123": "Henry", "654": "Joan"}
23 | users["admins"] = Data{"398": "Bill", "076": "Steve"}
24 |
25 | // Iterate over the map of maps.
26 | for key, data := range users {
27 | fmt.Println(key)
28 | for key, value := range data {
29 | fmt.Println("\t", key, value)
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/8K-IZgJFSg
5 |
6 | // Declare and make a map of integer values with a string as the key. Populate the
7 | // map with five values and iterate over the map to display the key/value pairs.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare and make a map of integer type values.
17 | departments := make(map[string]int)
18 |
19 | // Initialize some data into the map.
20 | departments["IT"] = 20
21 | departments["Marketing"] = 15
22 | departments["Executives"] = 5
23 | departments["Sales"] = 50
24 | departments["Security"] = 8
25 |
26 | // Display each key/value pair.
27 | for key, value := range departments {
28 | fmt.Printf("Dept: %s People: %d\n", key, value)
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/00-slides/day1/opening/slide1.md:
--------------------------------------------------------------------------------
1 | ## Special Features Of Go
2 |
3 | I may be biased, but I truly believe Go is an amazing language. It balances the efficiency of a lower level systems language with the most important features of a high-level modern language. This creates a programming environment that allows you to be incredibly productive, performant and fully in control; in Go you can write less code and do so much more. Here are some other special features about the language:
4 |
5 | #### * Comes with a robust standard library.
6 |
7 | #### * Works on a multitude of platforms.
8 |
9 | #### * Code is statically compiled so deployment is trivial.
10 |
11 | #### * The documentation is exemplary and complete, yet concise.
12 |
13 | #### * Comes with a tool to test, profile and benchmark your code.
14 |
15 | #### * Can interact with C libraries via cgo.
16 |
17 | #### [Next Slide](slide2.md)
18 | ___
19 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
20 |
--------------------------------------------------------------------------------
/02-array_slices_maps/01-arrays/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/Pa3mrTCcpB
5 |
6 | // Declare an array of 5 strings with each element initialized to its zero value.
7 | //
8 | // Declare a second array of 5 strings and initialize this array with literal string
9 | // values. Assign the second array to the first and display the results of the first array.
10 | package main
11 |
12 | import "fmt"
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare string arrays to hold names.
17 | var names [5]string
18 |
19 | // Declare an array pre-populated with friend's names.
20 | friends := [5]string{"Joe", "Ed", "Jim", "Erick", "Bill"}
21 |
22 | // Assign the array of friends to the names array.
23 | names = friends
24 |
25 | // Display each name in names.
26 | for _, name := range names {
27 | fmt.Println(name)
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/04-packaging_exporting/exercises/template1/toy/toy.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package toy contains support for managing toy inventory.
5 | package toy
6 |
7 | // Declare a struct type named Toy with four fields. Name string,
8 | // Weight int, onHand int and sold int.
9 |
10 | // Declare a function named New that accepts values for the
11 | // exported fields. Return a pointer of type Toy that is initialized
12 | // with the parameters.
13 |
14 | // Declare a method named OnHand with a pointer receiver that
15 | // returns the current on hand count.
16 |
17 | // Declare a method named UpdateOnHand with a pointer receiver that
18 | // updates and returns the current on hand count.
19 |
20 | // Declare a method named Sold with a pointer receiver that
21 | // returns the current sold count.
22 |
23 | // Declare a method named UpdateSold with a pointer receiver that
24 | // updates and returns the current sold count.
25 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/d1kRkbZ-iV
5 |
6 | // Sample program to show the components of a slice. It has a
7 | // length, capacity and the underlying array.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Create a slice with a length of 5 elements and a capacity of 8.
17 | slice := make([]string, 5, 8)
18 | slice[0] = "Apple"
19 | slice[1] = "Orange"
20 | slice[2] = "Banana"
21 | slice[3] = "Grape"
22 | slice[4] = "Plum"
23 |
24 | inspectSlice(slice)
25 | }
26 |
27 | // inspectSlice exposes the slice header for review.
28 | func inspectSlice(slice []string) {
29 | fmt.Printf("Length[%d] Capacity[%d]\n", len(slice), cap(slice))
30 | for i, v := range slice {
31 | fmt.Printf("[%d] %p %s\n",
32 | i,
33 | &slice[i],
34 | v)
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/asM7GXfJNk
5 |
6 | // Declare and initialize a variable of type int with the value of 20. Display
7 | // the _address of_ and _value of_ the variable.
8 | //
9 | // Declare and initialize a pointer variable of type int that points to the last
10 | // variable you just created. Display the _address of_ , _value of_ and the
11 | // _value that the pointer points to_.
12 | package main
13 |
14 | // Add imports.
15 |
16 | // main is the entry point for the application.
17 | func main() {
18 | // Declare an integer variable with the value of 20.
19 |
20 | // Display the address of and value of the variable.
21 |
22 | // Declare a pointer variable of type int. Assign the
23 | // address of the integer variable above.
24 |
25 | // Display the address of, value of and the value the pointer
26 | // points to.
27 | }
28 |
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/1xUWjHMB3I
5 |
6 | // Declare three variables that are initialized to their zero value and three
7 | // declared with a literal value. Declare variables of type string, int and
8 | // bool. Display the values of those variables.
9 | //
10 | // Declare a new variable of type float32 and initialize the variable by
11 | // converting the literal value of Pi (3.14).
12 | package main
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare variables that are set to their zero value.
17 |
18 | // Display the value of those variables.
19 |
20 | // Declare variables and initialize.
21 | // Using the short variable declaration operator.
22 |
23 | // Display the value of those variables.
24 |
25 | // Perform a type conversion.
26 |
27 | // Display the value of that variable.
28 | }
29 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/example6/example6.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/cK3y_qYUgd
5 |
6 | // Sample program to show how to declare and use variadic functions.
7 | package main
8 |
9 | import "fmt"
10 |
11 | // user is a struct type that declares user information.
12 | type user struct {
13 | id int
14 | name string
15 | }
16 |
17 | // main is the entry point for the application.
18 | func main() {
19 | // Declare and initialize a value of type user.
20 | u1 := user{
21 | id: 1432,
22 | name: "Betty",
23 | }
24 |
25 | // Declare and initialize a value of type user.
26 | u2 := user{
27 | id: 4367,
28 | name: "Janet",
29 | }
30 |
31 | // Display both user values.
32 | display(u1, u2)
33 | }
34 |
35 | // display can accept and display multiple values of user types.
36 | func display(users ...user) {
37 | for i := 0; i < len(users); i++ {
38 | fmt.Printf("%+v\n", users[i])
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/10-testing/exercises/template1/bench_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | /*
5 | http://golang.org/cmd/go/#hdr-Description_of_testing_flags
6 | go test -run=XXX -bench=.
7 | go test -run=XXX -bench=BenchmarkSprintf
8 | go test -run=XXX -bench=BenchmarkFormat
9 | go test -run=XXX -bench=BenchmarkAtoi
10 | */
11 |
12 | // Write three benchmark tests for converting an integer into a string. First using the
13 | // fmt.Sprintf function, then the strconv.FormatInt function and then strconv.Itoa.
14 | // Identify which function performs the best.
15 | package main
16 |
17 | // Add imports.
18 |
19 | // BenchmarkSprintf provides performance numbers for the fmt.Sprintf function.
20 | // fmt.Sprintf("%d", number)
21 |
22 | // BenchmarkFormat provides performance numbers for the strconv.FormatInt function.
23 | // strconv.FormatInt(number, 10)
24 |
25 | // BenchmarkItoa provides performance numbers for the strconv.Itoa function.
26 | // strconv.Itoa(number)
27 |
--------------------------------------------------------------------------------
/01-language_syntax/05-type_conversions/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/mhKlxSyuxr
5 |
6 | // Sample program to show how to declare and use a named type.
7 | package main
8 |
9 | import "fmt"
10 |
11 | // Duration is a named type that represents a duration
12 | // of time in Nanosecond.
13 | type Duration int64
14 |
15 | func main() {
16 | // Declare a variable of type Duration.
17 | var duration Duration
18 | fmt.Println(duration)
19 |
20 | // Declare a variable of type int64 and assign a value.
21 | nanosecond := int64(10)
22 |
23 | // Attempted to assign a variable of type int64 (base type of Duration) to
24 | // a variable of type Duration.
25 | // duration = nanosecond
26 |
27 | // ./example1.go:22: cannot use nanosecond (type int64) as type Duration in assignment
28 |
29 | // Convert a value of type int64 to type Duration.
30 | duration = Duration(nanosecond)
31 | fmt.Println(duration)
32 | }
33 |
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/-oeDmu2et8
5 |
6 | // Sample program to show how to declare and initialize struct types.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | )
12 |
13 | // example represents a type with different fields.
14 | type example struct {
15 | flag bool
16 | counter int16
17 | pi float32
18 | }
19 |
20 | // main is the entry point for the application.
21 | func main() {
22 | // Declare a variable of type example set to its
23 | // zero value.
24 | var e1 example
25 |
26 | // Display the value.
27 | fmt.Printf("%+v\n", e1)
28 |
29 | // Declare a variable of type example and init using
30 | // a struct literal.
31 | e2 := example{
32 | flag: true,
33 | counter: 10,
34 | pi: 3.141592,
35 | }
36 |
37 | // Display the field values.
38 | fmt.Println("Flag", e2.flag)
39 | fmt.Println("Counter", e2.counter)
40 | fmt.Println("Pi", e2.pi)
41 | }
42 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/exercises/template2/template2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/b6-FNFOToO
5 |
6 | // Declare a struct type and create a value of this type. Declare a function
7 | // that can change the value of some field in this struct type. Display the
8 | // value before and after the call to your function.
9 | package main
10 |
11 | // Add imports.
12 |
13 | // Declare a type named user.
14 |
15 | // Create a function that changes the value of one of the user fields.
16 | func funcName( /* add pointer parameter, add value parameter */ ) {
17 | // Use the pointer to change the value that the
18 | // pointer points to.
19 | }
20 |
21 | // main is the entry point for the application.
22 | func main() {
23 | // Create a variable of type user and initialize each field.
24 |
25 | // Display the value of the variable.
26 |
27 | // Share the variable with the function you declared above.
28 |
29 | // Display the value of the variable.
30 | }
31 |
--------------------------------------------------------------------------------
/02-array_slices_maps/01-arrays/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/DGr8Zp9L_w
5 |
6 | // Sample program to show how to declare and iterate over
7 | // arrays of different types.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare an array of five strings that is initialized
17 | // to its zero value.
18 | var strings [5]string
19 | strings[0] = "Apple"
20 | strings[1] = "Orange"
21 | strings[2] = "Banana"
22 | strings[3] = "Grape"
23 | strings[4] = "Plum"
24 |
25 | // Iterate over the array of strings.
26 | for i, fruit := range strings {
27 | fmt.Println(i, fruit)
28 | }
29 |
30 | // Declare an array of 4 integers that is initialized
31 | // with some values.
32 | numbers := [4]int{10, 20, 30, 40}
33 |
34 | // Iterate over the array of numbers.
35 | for i := 0; i < len(numbers); i++ {
36 | fmt.Println(i, numbers[i])
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/13-http/example3/template/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Sample Form
5 |
15 |
16 |
17 |
Add User
18 |
24 |
25 |
Existing Users
26 | {{if .Users}}
27 |
28 |
29 |
Name
Email
Phone
30 |
31 |
32 | {{range .Users}}
33 |
{{.Name}}
{{.Email}}
{{.Phone}}
34 | {{end}}
35 |
36 |
37 | {{else}}
38 |
(no users)
39 | {{end}}
40 |
41 |
42 |
--------------------------------------------------------------------------------
/10-testing/04-godebug/godebug.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/sKLLsUa5hH
5 |
6 | // export GODEBUG=schedtrace=1000
7 | // export GODEBUG=schedtrace=1000,scheddetail=1
8 |
9 | // Sample program to review scheduler stats.
10 | package main
11 |
12 | import (
13 | "sync"
14 | "time"
15 | )
16 |
17 | // Create a waitgroup.
18 | var wg sync.WaitGroup
19 |
20 | // main is the entry point for the application.
21 | func main() {
22 | // We are going to create 10 goroutines.
23 | wg.Add(10)
24 |
25 | // Create those 10 goroutines.
26 | for i := 0; i < 10; i++ {
27 | go goroutine()
28 | }
29 |
30 | // Wait for all the goroutines to complete.
31 | wg.Wait()
32 |
33 | // Wait to see the global runqueue deplete.
34 | time.Sleep(3 * time.Second)
35 | }
36 |
37 | // goroutine does some CPU bound work.
38 | func goroutine() {
39 | time.Sleep(time.Second)
40 |
41 | var count int
42 | for i := 0; i < 1e10; i++ {
43 | count++
44 | }
45 |
46 | wg.Done()
47 | }
48 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/example5/example5.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/6CAkumo0HI
5 |
6 | // Sample program to show how strings have a UTF-8 encoded byte array.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | "unicode/utf8"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare a string with both chinese and english characters.
17 | s := "世界 means world"
18 |
19 | // UTFMax is 4 -- up to 4 bytes per encoded rune.
20 | var buf [utf8.UTFMax]byte
21 |
22 | // Iterate over each character in the string.
23 | for i, r := range s {
24 | // Capture the number of bytes for this character.
25 | k := utf8.RuneLen(r)
26 |
27 | // Calculate the slice offset to slice the character out.
28 | j := i + k
29 |
30 | // Copy of character from the string to our buffer.
31 | copy(buf[:], s[i:j])
32 |
33 | // Display the details.
34 | fmt.Printf("%2d: %q; codepoint: %#6x; encoded bytes: %#v\n", i, r, r, buf[:k])
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/11-standard_library/03-writers_readers/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/jlTo1IV1RQ
5 |
6 | // The io.Reader and io.Writer interfaces allow you to compose all of these different bits together.
7 |
8 | // Sample program to show how different functions from the
9 | // standard library use the io.Writer interface.
10 | package main
11 |
12 | import (
13 | "bytes"
14 | "fmt"
15 | "os"
16 | )
17 |
18 | // main is the entry point for the application.
19 | func main() {
20 | // Create a Buffer value and write a string to the buffer.
21 | // Using the Write method that implements io.Writer.
22 | var b bytes.Buffer
23 | b.Write([]byte("Hello "))
24 |
25 | // Use Fprintf to concatenate a string to the Buffer.
26 | // Passing the address of a bytes.Buffer value for io.Writer.
27 | fmt.Fprintf(&b, "World!")
28 |
29 | // Write the content of the Buffer to the stdout device.
30 | // Passing the address of a os.File value for io.Writer.
31 | b.WriteTo(os.Stdout)
32 | }
33 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/01-methods/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/Rj0QfwVPhX
5 |
6 | // Declare a struct that represents a baseball player. Include name, atBats and hits.
7 | // Declare a method that calculates a players batting average. The formula is Hits / AtBats.
8 | // Declare a slice of this type and initialize the slice with several players. Iterate over
9 | // the slice displaying the players name and batting average.
10 | package main
11 |
12 | // Add imports.
13 |
14 | // Declare a struct that represents a ball player.
15 | // Include field called name, atBats and hits.
16 |
17 | // Declare a method that calculates the batting average for a batter.
18 | func ( /* receiver */ ) average() /* return type */ {
19 | }
20 |
21 | // main is the entry point for the application.
22 | func main() {
23 | // Create a slice of players and populate each player
24 | // with field values.
25 |
26 | // Display the batting average for each player in the slice.
27 | }
28 |
--------------------------------------------------------------------------------
/09-concurrency_patterns/readme.md:
--------------------------------------------------------------------------------
1 | ## Concurrency Patterns
2 | There are lots of different patterns we can create with goroutines and channels. Two interesting patterns are resource pooling and concurrent searching.
3 |
4 | ## Notes
5 |
6 | * The work code provides a pattern for giving work to a set number of goroutines without losing the guarantee.
7 | * The resource pooling code provides a pattern for managing resources that goroutines may need to acquire and release.
8 | * The search code provides a pattern for using multiple goroutines to perform concurrent work.
9 |
10 | ## Links
11 |
12 | https://github.com/gobridge/concurrency-patterns
13 |
14 | http://blog.golang.org/pipelines
15 |
16 | https://talks.golang.org/2012/concurrency.slide#1
17 |
18 | https://blog.golang.org/context
19 |
20 | http://blog.golang.org/advanced-go-concurrency-patterns
21 |
22 | http://talks.golang.org/2012/chat.slide
23 |
24 | ## Code Review
25 |
26 | [Task](task)
27 |
28 | [Pooling](pool)
29 |
30 | [Chat](chat)
31 | ___
32 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
33 |
--------------------------------------------------------------------------------
/10-testing/02-prediction/prediction_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/hwZqjJNdbm
5 |
6 | // go build -gcflags -m
7 |
8 | // Package prediction provides code to show how branch
9 | // prediction can affect performance.
10 | package prediction
11 |
12 | import (
13 | "math/rand"
14 | "testing"
15 | )
16 |
17 | func BenchmarkPredictable(b *testing.B) {
18 | data := make([]uint8, 1024)
19 |
20 | b.ResetTimer()
21 | for i := 0; i < b.N; i++ {
22 | crunch(data)
23 | }
24 | }
25 |
26 | func BenchmarkUnpredictable(b *testing.B) {
27 | data := make([]uint8, 1024)
28 | rand.Seed(0)
29 |
30 | // Fill data with (pseudo) random noise
31 | for i := range data {
32 | data[i] = uint8(rand.Uint32())
33 | }
34 |
35 | b.ResetTimer()
36 | for i := 0; i < b.N; i++ {
37 | crunch(data)
38 | }
39 | }
40 |
41 | func crunch(data []uint8) uint8 {
42 | var sum uint8
43 | for _, v := range data {
44 | if v < 128 {
45 | sum--
46 | } else {
47 | sum++
48 | }
49 | }
50 | return sum
51 | }
52 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/FWmGnVUDoA
5 |
6 | // Sample program to show the basic concept of using a pointer
7 | // to share data.
8 | package main
9 |
10 | import "fmt"
11 |
12 | // main is the entry point for the application.
13 | func main() {
14 | // Declare variable of type int with a value of 10.
15 | count := 10
16 |
17 | // Display the "value of" and "address of" count.
18 | println("Before:", count, &count)
19 |
20 | // Pass the "address of" the variable count.
21 | increment(&count)
22 |
23 | println("After: ", count, &count)
24 | }
25 |
26 | // increment declares count as a pointer variable whose value is
27 | // always an address and points to values of type int.
28 | func increment(inc *int) {
29 | // Increment the value that the "pointer points to". (de-referencing)
30 | *inc++
31 | println("Inc: ", *inc, &inc, inc)
32 |
33 | // Do this to prevent inlining.
34 | var x int
35 | fmt.Sprintf("Prevent Inlining: %d", x)
36 | }
37 |
--------------------------------------------------------------------------------
/13-http/api/main.go:
--------------------------------------------------------------------------------
1 | // This program provides a sample web service that implements a
2 | // RESTFul CRUD API against a MongoDB database.
3 | package main
4 |
5 | import (
6 | "log"
7 | "net/http"
8 | "os"
9 | "os/signal"
10 |
11 | "github.com/gobridge/gotraining/13-http/api/routes"
12 | )
13 |
14 | // init is called before main. We are using init to customize logging output.
15 | func init() {
16 | log.SetFlags(log.LstdFlags | log.Lmicroseconds | log.Lshortfile)
17 | }
18 |
19 | // main is the entry point for the application.
20 | func main() {
21 | log.Println("main : Started")
22 |
23 | // Check the environment for a configured port value.
24 | port := os.Getenv("PORT")
25 | if port == "" {
26 | port = "3000"
27 | }
28 |
29 | // Create this goroutine to run the web server.
30 | go func() {
31 | log.Println("listener : Started : Listening on: http://localhost:" + port)
32 | http.ListenAndServe(":"+port, routes.API())
33 | }()
34 |
35 | // Listen for an interrupt signal from the OS.
36 | sigChan := make(chan os.Signal, 1)
37 | signal.Notify(sigChan, os.Interrupt)
38 | <-sigChan
39 |
40 | log.Println("main : Completed")
41 | }
42 |
--------------------------------------------------------------------------------
/04-packaging_exporting/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Create a package named toy with a single exported struct type named Toy. Add
5 | // the exported fields Name and Weight. Then add two unexported fields named
6 | // onHand and sold. Declare a factory function called New to create values of
7 | // type toy and accept parameters for the exported fields. Then declare methods
8 | // that return and update values for the unexported fields.
9 | //
10 | // Create a program that imports the toy package. Use the New function to create a
11 | // value of type toy. Then use the methods to set the counts and display the
12 | // field values of that toy value.
13 | package main
14 |
15 | // Add imports.
16 |
17 | // main is the entry point for the application.
18 | func main() {
19 | // Use the New function from the toy package to create a value of
20 | // type toy.
21 |
22 | // Use the methods from the toy value to set some initialize
23 | // values.
24 |
25 | // Display each field separately from the toy value.
26 | }
27 |
--------------------------------------------------------------------------------
/00-slides/day_2_training.md:
--------------------------------------------------------------------------------
1 | ## Go Training - Day 2
2 | On this day we dive deeper into Go. We learn about packaging, exporting, using pointers, composition, error handling, concurrency, race conditions, and channels.
3 |
4 | *Note: This material has been designed to be taught in a classroom environment. The code is well commented but missing some of the contextual concepts and ideas that will be covered in class.*
5 |
6 | #### Packaging and Exporting
7 | [Packaging and Exporting](../04-packaging_exporting/readme.md)
8 |
9 | #### Using Pointers
10 | [Nature Of Types](../05-using_pointers/readme.md)
11 |
12 | #### Composition
13 | [Composition](../06-composition/readme.md)
14 |
15 | #### Error Handling
16 | [Error Handling](../07-error_handling/readme.md)
17 |
18 | #### Concurrency, Race Conditions and Channels
19 | [Goroutines](../08-concurrency_channels/01-goroutines/readme.md) |
20 | [Race Conditions](../08-concurrency_channels/02-race_conditions/readme.md) |
21 | [Channels](../08-concurrency_channels/03-channels/readme.md)
22 | ___
23 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
24 |
--------------------------------------------------------------------------------
/07-error_handling/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/8x6kDZxPWK
5 |
6 | // Sample program to show how the default error type is implemented.
7 | package main
8 |
9 | import "fmt"
10 |
11 | // http://golang.org/pkg/builtin/#error
12 | type error interface {
13 | Error() string
14 | }
15 |
16 | // http://golang.org/src/pkg/errors/errors.go
17 | type errorString struct {
18 | s string
19 | }
20 |
21 | // http://golang.org/src/pkg/errors/errors.go
22 | func (e *errorString) Error() string {
23 | return e.s
24 | }
25 |
26 | // http://golang.org/src/pkg/errors/errors.go
27 | // New returns an error that formats as the given text.
28 | func New(text string) error {
29 | return &errorString{text}
30 | }
31 |
32 | // main is the entry point for the application.
33 | func main() {
34 | if err := webCall(); err != nil {
35 | fmt.Println(err)
36 | return
37 | }
38 |
39 | fmt.Println("Life is good")
40 | }
41 |
42 | // webCall performs a web operation.
43 | func webCall() error {
44 | return New("Bad Request")
45 | }
46 |
--------------------------------------------------------------------------------
/11-standard_library/03-writers_readers/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/MxcJ581bt6
5 |
6 | // Download any document from the web and display the content in
7 | // the terminal and write it to a file at the same time.
8 | package main
9 |
10 | // Add imports.
11 |
12 | // main is the entry point for the application.
13 | func main() {
14 | // Download the RSS feed for "http://www.goinggo.net/feeds/posts/default".
15 | // Check for errors.
16 |
17 | // Arrange for the response Body to be Closed using defer.
18 |
19 | // Declare a slice of io.Writer interface values.
20 |
21 | // Append stdout to the slice of writers.
22 |
23 | // Open a file named "goinggo.rss" and check for errors.
24 |
25 | // Close the file when the function returns.
26 |
27 | // Append the file to the slice of writers.
28 |
29 | // Create a MultiWriter interface value from the writers
30 | // inside the slice of io.Writer values.
31 |
32 | // Write the response to both the stdout and file using the
33 | // MultiWriter. Check for errors.
34 | }
35 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/pUtHSTN0Ef
5 |
6 | // Declare and initialize a variable of type int with the value of 20. Display
7 | // the _address of_ and _value of_ the variable.
8 | //
9 | // Declare and initialize a pointer variable of type int that points to the last
10 | // variable you just created. Display the _address of_ , _value of_ and the
11 | // _value that the pointer points to_.
12 | package main
13 |
14 | import "fmt"
15 |
16 | // main is the entry point for the application.
17 | func main() {
18 | // Declare an integer variable with the value of 20.
19 | value := 20
20 |
21 | // Display the address of and value of the variable.
22 | fmt.Println("Address Of:", &value, "Value Of:", value)
23 |
24 | // Declare a pointer variable of type int. Assign the
25 | // address of the integer variable above.
26 | p := &value
27 |
28 | // Display the address of, value of and the value the pointer
29 | // points to.
30 | fmt.Println("Address Of:", &p, "Value Of:", p, "Points To:", *p)
31 | }
32 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/03-embedding/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/e5O_Dx5VpM
5 |
6 | // Sample program to show how what we are doing is NOT embedding
7 | // a type but just using a type as a field.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // user defines a user in the program.
15 | type user struct {
16 | name string
17 | email string
18 | }
19 |
20 | // notify implements a method that can be called via
21 | // a value of type user.
22 | func (u *user) notify() {
23 | fmt.Printf("Sending user email To %s<%s>\n",
24 | u.name,
25 | u.email)
26 | }
27 |
28 | // admin represents an admin user with privileges.
29 | type admin struct {
30 | person user // NOT Embedding
31 | level string
32 | }
33 |
34 | // main is the entry point for the application.
35 | func main() {
36 | // Create an admin user.
37 | ad := admin{
38 | person: user{
39 | name: "john smith",
40 | email: "john@yahoo.com",
41 | },
42 | level: "super",
43 | }
44 |
45 | // We can access fields methods.
46 | ad.person.notify()
47 | }
48 |
--------------------------------------------------------------------------------
/05-using_pointers/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/9_MSdcdlNQ
5 |
6 | // Declare a struct type named Point with two fields, X and Y of type int.
7 | // Implement a factory function for this type and a method that accept a value
8 | // of this type and calculates the distance between the two points. What is
9 | // the nature of this type?
10 | package main
11 |
12 | // Add imports.
13 |
14 | // Declare struct type named Point that represents a point in space.
15 |
16 | // Declare a function named New that returns a Point based on X and Y
17 | // positions on a graph.
18 |
19 | // Declare a method named Distance that finds the length of the hypotenuse
20 | // between two points. Pass one point in and return the answer.
21 | // Formula is the square root of (x2 - x1)^2 + (y2 - y1)^2
22 | // Use the math.Pow and math.Sqrt functions.
23 |
24 | // main is the entry point for the application.
25 | func main() {
26 | // Declare the first point.
27 |
28 | // Declare the second point.
29 |
30 | // Calculate the distance and display the result.
31 | }
32 |
--------------------------------------------------------------------------------
/11-standard_library/readme.md:
--------------------------------------------------------------------------------
1 | ## Standard Library
2 |
3 | The Go standard library is a set of core packages that enhance and extend the language. These packages add to the number of different types of programs you can write without the need to build your own packages or download packages others have published. Since these packages are tied to the language, they come with some special guarantees that make the standard library special and something you want to leverage as much as possible.
4 |
5 | ## Guarantees
6 |
7 | * They will always exist for each minor release of the language.
8 | * They will honor the backwards compatibility promise.
9 | * They are part of the dev, build and release process for Go.
10 | * They are maintained and reviewed by Go contributors.
11 | * They are tested and benchmarked with each new release of the language.
12 |
13 | ## Package Review
14 |
15 | [Logging](../11-standard_library/01-logging/readme.md)
16 |
17 | [Encoding](../11-standard_library/02-encoding/readme.md)
18 |
19 | [Writers/Readers](../11-standard_library/03-writers_readers/readme.md)
20 | ___
21 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
22 |
--------------------------------------------------------------------------------
/04-packaging_exporting/exercises/exercise1/toy/toy.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package toy contains support for managing toy inventory.
5 | package toy
6 |
7 | // Toy represents a toy we sell.
8 | type Toy struct {
9 | Name string
10 | Weight int
11 |
12 | onHand int
13 | sold int
14 | }
15 |
16 | // New creates values of type toy.
17 | func New(name string, weight int) *Toy {
18 | return &Toy{
19 | Name: name,
20 | Weight: weight,
21 | }
22 | }
23 |
24 | // OnHand returns the current number of this
25 | // toy on hand.
26 | func (t *Toy) OnHand() int {
27 | return t.onHand
28 | }
29 |
30 | // UpdateOnHand updates the on hand count and
31 | // returns the current value.
32 | func (t *Toy) UpdateOnHand(count int) int {
33 | t.onHand = t.onHand + count
34 | return t.onHand
35 | }
36 |
37 | // Sold returns the current number of this
38 | // toy sold.
39 | func (t *Toy) Sold() int {
40 | return t.sold
41 | }
42 |
43 | // UpdateSold updates the sold count and
44 | // returns the current value.
45 | func (t *Toy) UpdateSold(count int) int {
46 | t.sold = t.sold + count
47 | return t.sold
48 | }
49 |
--------------------------------------------------------------------------------
/01-language_syntax/06-functions/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/p0vlsW5sVL
5 |
6 | // Declare a struct type to maintain information about a user. Declare a function
7 | // that creates value of and returns pointers of this type and an error value. Call
8 | // this function from main and display the value.
9 | //
10 | // Make a second call to your function but this time ignore the value and just test
11 | // the error value.
12 | package main
13 |
14 | // Add imports.
15 |
16 | // Declare a type named user.
17 |
18 | // Declare a function that creates user type values and returns a pointer
19 | // to that value and an error value of nil.
20 | func funcName() /* (pointer return arg, error return arg) */ {
21 | // Create a value of type user and return the proper values.
22 | }
23 |
24 | // main is the entry point for the application.
25 | func main() {
26 | // Use the function to create a value of type user. Check
27 | // the error being returned.
28 |
29 | // Display the value that the pointer points to.
30 |
31 | // Call the function again and just check the error.
32 | }
33 |
--------------------------------------------------------------------------------
/07-error_handling/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/4YHAbpynl3
5 |
6 | // Sample program to show how to use error variables to help the
7 | // caller determine the exact error being returned.
8 | package main
9 |
10 | import (
11 | "errors"
12 | "fmt"
13 | )
14 |
15 | var (
16 | // ErrBadRequest is returned when there are problems with the request.
17 | ErrBadRequest = errors.New("Bad Request")
18 |
19 | // ErrMovedPermanently is returned when a 301/302 is returned.
20 | ErrMovedPermanently = errors.New("Moved Permanently")
21 | )
22 |
23 | // main is the entry point for the application.
24 | func main() {
25 | if err := webCall(); err != nil {
26 | switch err {
27 | case ErrBadRequest:
28 | fmt.Println("Bad Request Occurred")
29 | return
30 |
31 | case ErrMovedPermanently:
32 | fmt.Println("The URL moved, check it again")
33 | return
34 |
35 | default:
36 | fmt.Println(err)
37 | return
38 | }
39 | }
40 |
41 | fmt.Println("Life is good")
42 | }
43 |
44 | // webCall performs a web operation.
45 | func webCall() error {
46 | return ErrBadRequest
47 | }
48 |
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/ZgPw0LU_Nv
5 |
6 | // Sample program to show how to declare, initialize and iterate
7 | // over a map. Shows how iterating over a map is random.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // user defines a user in the program.
15 | type user struct {
16 | name string
17 | email string
18 | }
19 |
20 | // main is the entry point for the application.
21 | func main() {
22 | // Declare and make a map that stores values
23 | // of type user with a key of type string.
24 | users := make(map[string]user)
25 |
26 | // Add key/value pairs to the map.
27 | users["Rob"] = user{"Roy", "Rob"}
28 | users["Ford"] = user{"Henry", "Ford"}
29 | users["Mouse"] = user{"Mickey", "Mouse"}
30 | users["Jackson"] = user{"Michael", "Jackson"}
31 |
32 | // Iterate over the map.
33 | for key, value := range users {
34 | fmt.Println(key, value)
35 | }
36 |
37 | fmt.Println()
38 |
39 | // Iterate over the map and notice the
40 | // results are different.
41 | for key := range users {
42 | fmt.Println(key)
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/mPKmyGNR2L
5 |
6 | // Declare a nil slice of integers. Declare a nil slice of integers. Create a
7 | // loop that appends 10 values to the slice. Iterate over the slice and display
8 | // each value. Iterate over the slice and display each value.
9 | //
10 | // Declare a slice of five strings and initialize the slice with string literal
11 | // values. Display all the elements. Take a slice of index one and two
12 | // and display the index position and value of each element in the new slice.
13 | package main
14 |
15 | // Add imports.
16 |
17 | // main is the entry point for the application.
18 | func main() {
19 | // Declare a nil slice of integers.
20 |
21 | // Appends numbers to the slice.
22 |
23 | // Display each value in the slice.
24 |
25 | // Declare a slice of strings and populate the slice with names.
26 |
27 | // Display each index position and slice value.
28 |
29 | // // Take a slice of index 1 and 2 of the slice of strings.
30 |
31 | // Display each index position and slice values for the new slice.
32 | }
33 |
--------------------------------------------------------------------------------
/11-standard_library/02-encoding/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/OkIHsVwMQ7
5 |
6 | // Create a file with an array of JSON documents that contain a user name and email address. Declare a struct
7 | // type that maps to the JSON document. Using the json package, read the file and create a slice of this struct
8 | // type. Display the slice.
9 | //
10 | // Marshal the slice into pretty print strings and display each element.
11 | package main
12 |
13 | // Add imports.
14 |
15 | // Declare a struct type named user with two fields. Name of type string and
16 | // Email of type string. Add tags for each field for the unmarshal call.
17 |
18 | // main is the entry point for the application.
19 | func main() {
20 | // Use the os package to Open the JSON file. Check for errors.
21 |
22 | // Schedule the file to be closed once the function returns.
23 |
24 | // Declare a nil slice of user struct types.
25 | // Decode the JSON from the file into the slice. Check for errors.
26 |
27 | // Iterate over the slice and display each user value.
28 |
29 | // Marshal each user value and display the JSON. Check for errors.
30 | }
31 |
--------------------------------------------------------------------------------
/01-language_syntax/05-type_conversions/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/-WjYGqauiY
5 |
6 | // Declare a named type called counter with a base type of int. Declare a variable
7 | // named c of type counter set to its zero value. Display the value of c.
8 | //
9 | // Declare a variable named c2 of type counter set to the value of 10. Display the value
10 | // of c2.
11 | //
12 | // Declare a variable named i of the base type int. Attempt to assign the value
13 | // of i to c. Does the compiler allow the assignment?
14 | package main
15 |
16 | // Add imports.
17 |
18 | // Declare the named type called counter with a base
19 | // type of int.
20 |
21 | // main is the entry point for the application.
22 | func main() {
23 | // Declare a variable named c of type counter
24 | // set to its zero value.
25 |
26 | // Display the value of c.
27 |
28 | // Declare a variable named c2 of type counter
29 | // set to the value of 10.
30 |
31 | // Display the value of c2.
32 |
33 | // Declare a variable named i of the base type int.
34 |
35 | // Assign the value of i to the variable named c.
36 |
37 | // Does it compile?
38 | }
39 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/03-embedding/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/UkrDXkk-Ch
5 |
6 | // Sample program to show how to embed a type into another type and
7 | // the relationship between the inner and outer type.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // user defines a user in the program.
15 | type user struct {
16 | name string
17 | email string
18 | }
19 |
20 | // notify implements a method that can be called via
21 | // a value of type user.
22 | func (u *user) notify() {
23 | fmt.Printf("Sending user email To %s<%s>\n",
24 | u.name,
25 | u.email)
26 | }
27 |
28 | // admin represents an admin user with privileges.
29 | type admin struct {
30 | user // Embedded Type
31 | level string
32 | }
33 |
34 | // main is the entry point for the application.
35 | func main() {
36 | // Create an admin user.
37 | ad := admin{
38 | user: user{
39 | name: "john smith",
40 | email: "john@yahoo.com",
41 | },
42 | level: "super",
43 | }
44 |
45 | // We can access the inner type's method directly.
46 | ad.user.notify()
47 |
48 | // The inner type's method is promoted.
49 | ad.notify()
50 | }
51 |
--------------------------------------------------------------------------------
/10-testing/01-testing/example1/example1_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample test to show how to write a basic unit test.
5 | package example1
6 |
7 | import (
8 | "net/http"
9 | "testing"
10 | )
11 |
12 | const succeed = "\u2713"
13 | const failed = "\u2717"
14 |
15 | // TestDownload validates the http Get function can download content.
16 | func TestDownload(t *testing.T) {
17 | url := "http://www.goinggo.net/feeds/posts/default?alt=rss"
18 | statusCode := 200
19 |
20 | t.Log("Given the need to test downloading content.")
21 | {
22 | t.Logf("\tWhen checking \"%s\" for status code \"%d\"", url, statusCode)
23 | {
24 | resp, err := http.Get(url)
25 | if err != nil {
26 | t.Fatal("\t\tShould be able to make the Get call.",
27 | failed, err)
28 | }
29 | t.Log("\t\tShould be able to make the Get call.",
30 | succeed)
31 |
32 | defer resp.Body.Close()
33 |
34 | if resp.StatusCode == statusCode {
35 | t.Logf("\t\tShould receive a \"%d\" status code. %v",
36 | statusCode, succeed)
37 | } else {
38 | t.Errorf("\t\tShould receive a \"%d\" status code. %v %v",
39 | statusCode, failed, resp.StatusCode)
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/00-slides/day1/quick/helloHTTP/helloHTTP.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/c44Q5OiX5z
5 |
6 | // Sample program to show off Go and check programming environment.
7 | package main
8 |
9 | import (
10 | "encoding/json"
11 | "log"
12 | "net/http"
13 | )
14 |
15 | type (
16 | // hello holds a message.
17 | hello struct {
18 | Message string
19 | }
20 | )
21 |
22 | // main is the entry point for the application.
23 | func main() {
24 | http.HandleFunc("/english", helloEnglish)
25 | http.HandleFunc("/chinese", helloChinese)
26 | http.ListenAndServe("localhost:9999", nil)
27 | }
28 |
29 | // helloEnglish sends a greeting in English.
30 | func helloEnglish(w http.ResponseWriter, r *http.Request) {
31 | err := json.NewEncoder(w).Encode(hello{"Hello World"})
32 | if err != nil {
33 | log.Println("Error encoding JSON", err)
34 | return
35 | }
36 | log.Println("Sent English")
37 | }
38 |
39 | // helloChinese sends a greeting in Chinese.
40 | func helloChinese(w http.ResponseWriter, r *http.Request) {
41 | err := json.NewEncoder(w).Encode(hello{"你好世界"})
42 | if err != nil {
43 | log.Println("Error encoding JSON", err)
44 | return
45 | }
46 | log.Println("Sent Chinese")
47 | }
48 |
--------------------------------------------------------------------------------
/05-using_pointers/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/5KL4HipSJ-
5 |
6 | // Declare a struct type named Point with two fields, X and Y of type int.
7 | // Implement a factory function for this type and a method that accept a value
8 | // of this type and calculates the distance between the two points. What is
9 | // the nature of this type.
10 | package main
11 |
12 | import (
13 | "fmt"
14 | "math"
15 | )
16 |
17 | // Point represents a point in space.
18 | type Point struct {
19 | X int
20 | Y int
21 | }
22 |
23 | // New returns a Point based on X and Y positions on a graph.
24 | func New(x int, y int) Point {
25 | return Point{x, y}
26 | }
27 |
28 | // Distance finds the length of the hypotenuse between two points.
29 | // Formula is the square root of (x2 - x1)^2 + (y2 - y1)^2
30 | func (p Point) Distance(p2 Point) float64 {
31 | first := math.Pow(float64(p2.X-p.X), 2)
32 | second := math.Pow(float64(p2.Y-p.Y), 2)
33 | return math.Sqrt(first + second)
34 | }
35 |
36 | // main is the entry point for the application.
37 | func main() {
38 | p1 := New(37, -76)
39 | p2 := New(26, -80)
40 |
41 | dist := p1.Distance(p2)
42 | fmt.Println("Distance", dist)
43 | }
44 |
--------------------------------------------------------------------------------
/01-language_syntax/05-type_conversions/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/KIdESKQc8C
5 |
6 | // Declare a named type called counter with a base type of int. Declare a variable
7 | // named c of type counter set to its zero value. Display the value of c.
8 | //
9 | // Declare a variable named c2 of type counter set to the value of 10. Display the value
10 | // of c2.
11 | //
12 | // Declare a variable named i of the base type int. Attempt to assign the value
13 | // of i to c. Does the compiler allow the assignment?
14 | package main
15 |
16 | import "fmt"
17 |
18 | // counter is a named type for counting.
19 | type counter int
20 |
21 | // main is the entry point for the application.
22 | func main() {
23 | // Declare a variable of type counter.
24 | var c counter
25 |
26 | // Display the value of c.
27 | fmt.Println(c)
28 |
29 | // Declare a second variable of type counter. Set
30 | // the value to 10.
31 | c2 := counter(10)
32 |
33 | // Display the value of c2.
34 | fmt.Println(c2)
35 |
36 | // Declare a variable named i of type int.
37 | i := 1
38 |
39 | // Assign the value of i to the variable named c.
40 | c = i
41 |
42 | // Does the program compile?
43 | }
44 |
--------------------------------------------------------------------------------
/01-language_syntax/06-functions/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/fSjQ3caTy1
5 |
6 | // Declare a struct type to maintain information about a user. Declare a function
7 | // that creates value of and returns pointers of this type and an error value. Call
8 | // this function from main and display the value.
9 | //
10 | // Make a second call to your function but this time ignore the value and just test
11 | // the error value.
12 | package main
13 |
14 | import "fmt"
15 |
16 | // user represents a user in the system.
17 | type user struct {
18 | name string
19 | email string
20 | }
21 |
22 | // main is the entry point for the application.
23 | func main() {
24 | // Create a value of type user.
25 | u, err := newUser()
26 | if err != nil {
27 | fmt.Println(err)
28 | return
29 | }
30 |
31 | // Display the value.
32 | fmt.Println(*u)
33 |
34 | // Call the function and just check the error on the return.
35 | _, err = newUser()
36 | if err != nil {
37 | fmt.Println(err)
38 | return
39 | }
40 | }
41 |
42 | // newUser creates and returns pointers of user type values.
43 | func newUser() (*user, error) {
44 | return &user{"Bill", "bill@ardanstudios.com"}, nil
45 | }
46 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/01-methods/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/C8Z_MiYKbc
5 |
6 | // Declare a struct that represents a baseball player. Include name, atBats and hits.
7 | // Declare a method that calculates a players batting average. The formula is Hits / AtBats.
8 | // Declare a slice of this type and initialize the slice with several players. Iterate over
9 | // the slice displaying the players name and batting average.
10 | package main
11 |
12 | import "fmt"
13 |
14 | // batter represents a playing in the game.
15 | type batter struct {
16 | name string
17 | atBats int
18 | hits int
19 | }
20 |
21 | // average calculates the batting average for a batter.
22 | func (b *batter) average() float64 {
23 | return float64(b.hits) / float64(b.atBats)
24 | }
25 |
26 | // main is the entry point for the application.
27 | func main() {
28 | // Create a few players.
29 | players := []batter{
30 | {"bill", 10, 7},
31 | {"jim", 12, 6},
32 | {"ed", 6, 4},
33 | }
34 |
35 | // Display the batting average for each player.
36 | for _, player := range players {
37 | average := player.average() * 1000
38 | fmt.Printf("%s: AVG[.%.f]\n", player.name, average)
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/04-packaging_exporting/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Create a package named toy with a single exported struct type named Toy. Add
5 | // the exported fields Name and Weight. Then add two unexported fields named
6 | // onHand and sold. Declare a factory function called New to create values of
7 | // type toy and accept parameters for the exported fields. Then declare methods
8 | // that return and update values for the unexported fields.
9 | //
10 | // Create a program that imports the toy package. Use the New function to create a
11 | // value of type toy. Then use the methods to set the counts and display the
12 | // field values of that toy value.
13 | package main
14 |
15 | import (
16 | "fmt"
17 |
18 | "github.com/gobridge/gotraining/04-packaging_exporting/exercises/exercise1/toy"
19 | )
20 |
21 | // main is the entry point for the application.
22 | func main() {
23 | // Create a value of type toy.
24 | toy := toy.New("Bat", 28)
25 |
26 | // Update the counts.
27 | toy.UpdateOnHand(100)
28 | toy.UpdateSold(2)
29 |
30 | // Display each field separately.
31 | fmt.Println("Name", toy.Name)
32 | fmt.Println("Weight", toy.Weight)
33 | fmt.Println("OnHand", toy.OnHand())
34 | fmt.Println("Sold", toy.Sold())
35 | }
36 |
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/AzDUqwkM58
5 |
6 | // Sample program to show how the goroutine scheduler
7 | // will time slice goroutines on a single thread.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "sync"
13 | )
14 |
15 | // wg is used to wait for the program to finish.
16 | var wg sync.WaitGroup
17 |
18 | // main is the entry point for all Go programs.
19 | func main() {
20 | // Add a count of two, one for each goroutine.
21 | wg.Add(2)
22 |
23 | // Create two goroutines.
24 | fmt.Println("Create Goroutines")
25 | go printPrime("A")
26 | go printPrime("B")
27 |
28 | // Wait for the goroutines to finish.
29 | fmt.Println("Waiting To Finish")
30 | wg.Wait()
31 |
32 | fmt.Println("Terminating Program")
33 | }
34 |
35 | // printPrime displays prime numbers for the first 5000 numbers.
36 | func printPrime(prefix string) {
37 | next:
38 | for outer := 2; outer < 5000; outer++ {
39 | for inner := 2; inner < outer; inner++ {
40 | if outer%inner == 0 {
41 | continue next
42 | }
43 | }
44 | fmt.Printf("%s:%d\n", prefix, outer)
45 | }
46 |
47 | fmt.Println("Completed", prefix)
48 |
49 | // Tell main we are done.
50 | wg.Done()
51 | }
52 |
--------------------------------------------------------------------------------
/13-http/example1/main.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/leTrm6v1yG
5 |
6 | // Sample program to show how to implement a handler function
7 | // with the http package.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "net/http"
13 | )
14 |
15 | func main() {
16 | // Like many packages in the standard library, the http package has
17 | // convenience methods that are declared on the package level. These methods
18 | // actually delegate to an underlying structure that you can initialize
19 | // yourself. In this example, we are adding a handler to the http.DefaultServeMux
20 | http.HandleFunc("/", HelloHandler)
21 |
22 | // ListenAndServe will listen on the specified host:port combo. Passing nil
23 | // as the second argument means we will be using the http.DefaultServeMux as
24 | // our http handler
25 | http.ListenAndServe(":4000", nil)
26 | }
27 |
28 | // HelloHandler shows how the http Handlers are the universal interface for
29 | // handling http stuff, you will see that many Go developers rally around the
30 | // http.Handler interface.
31 | func HelloHandler(w http.ResponseWriter, r *http.Request) {
32 | // Fprintln is a nice way to write formatted text out to a io.Writer
33 | fmt.Fprintln(w, "Hello world")
34 | }
35 |
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/H-h1cbBW3B
5 |
6 | // Create a program that declares two anonymous functions. Once that counts up to
7 | // 100 from 0 and one that counts down to 0 from 100. Display each number with an
8 | // unique identifier for each goroutine. Then create goroutines from these functions
9 | // and don't let main return until the goroutines complete.
10 | //
11 | // Run the program in parallel.
12 | package main
13 |
14 | // main is the entry point for all Go programs.
15 | func main() {
16 | // Declare a wait group and set the count to two.
17 |
18 | // Allocate two contexts for the scheduler to use in the
19 | // second part of this exercise.
20 |
21 | // Declare an anonymous function and create a goroutine.
22 | {
23 | // Declare a loop that counts down from 100 to 0 and
24 | // display each value.
25 |
26 | // Decrements the count of the wait group.
27 | }
28 |
29 | // Declare an anonymous function and create a goroutine.
30 | {
31 | // Declare a loop that counts up from 0 to 100 and
32 | // display each value.
33 |
34 | // Decrements the count of the wait group.
35 | }
36 |
37 | // Wait for the goroutines to finish.
38 | }
39 |
--------------------------------------------------------------------------------
/14-cli/04-patterns/readme.md:
--------------------------------------------------------------------------------
1 | ## Pattern Matching
2 |
3 | A fundamental convenience provided by shells is pattern matching of files.
4 | Let's initialize a directory with some files:
5 |
6 | touch a b1 c1 01.txt 02.txt
7 |
8 | We can now match against these four files in various ways using patterns.
9 |
10 | # display info for all files ending in '.txt': 01.txt 02.txt
11 | # the "star" will match any number of characters (including zero)
12 | ls -l *.txt
13 |
14 | # list all files starting with a lowercase letter: a b1 c1
15 | # character classes are case-sensitive and match exactly one character
16 | echo [a-z]*
17 |
18 | # list all files that do _not_ end with a number: a 01.txt 02.txt
19 | echo *[!0-9]
20 |
21 | # remove all files with names consisting of two characters: b1 c1
22 | # question marks match exactly one character each
23 | rm ??
24 |
25 | Pattern matching is the default behavior. To instead specify an argument or
26 | filename containing a wildcard character or whitespace, it can be wrapped in
27 | either single or double quotes, or the special character can be escaped with a
28 | backslash, for example:
29 |
30 | # create two new files
31 | touch filename\ with\ spaces "more spaces"
32 | ___
33 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
34 |
--------------------------------------------------------------------------------
/11-standard_library/02-encoding/example4/example4.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/TOYrZJoLei
5 |
6 | // Sample program to show how write a custom Unmarshal and Marshal functions.
7 | package main
8 |
9 | import (
10 | "encoding/json"
11 | "fmt"
12 | "time"
13 | )
14 |
15 | // NullableTime represents a nullable time for our sample.
16 | type NullableTime struct {
17 | time.Time
18 | }
19 |
20 | // MarshalJSON implements the Marshaler interface.
21 | func (t NullableTime) MarshalJSON() ([]byte, error) {
22 | if t.IsZero() {
23 | return []byte(`null`), nil
24 | }
25 |
26 | return []byte(`"` + t.Format(time.RFC3339) + `"`), nil
27 | }
28 |
29 | // UnmarshalJSON implements the Unmarshaler interface.
30 | func (t *NullableTime) UnmarshalJSON(b []byte) error {
31 | if string(b) == "null" {
32 | t.Time = time.Time{}
33 | return nil
34 | }
35 |
36 | tt, err := time.Parse(`"`+time.RFC3339+`"`, string(b))
37 | if err != nil {
38 | return err
39 | }
40 |
41 | t.Time = tt
42 | return nil
43 | }
44 |
45 | // main is the entry point for the application.
46 | func main() {
47 | var n NullableTime
48 | if err := json.Unmarshal([]byte("null"), &n); err != nil {
49 | fmt.Println(err)
50 | return
51 | }
52 |
53 | fmt.Printf("%+v", n)
54 | }
55 |
--------------------------------------------------------------------------------
/templates/layout.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/LJETaLkVl0
5 |
6 | // go build -race
7 |
8 | // Sample program to show how to use the atomic package to
9 | // provide safe access to numeric types.
10 | package main
11 |
12 | import (
13 | "fmt"
14 | "runtime"
15 | "sync"
16 | "sync/atomic"
17 | )
18 |
19 | // counter is a variable incremented by all goroutines.
20 | var counter int64
21 |
22 | // wg is used to wait for the program to finish.
23 | var wg sync.WaitGroup
24 |
25 | // main is the entry point for all Go programs.
26 | func main() {
27 | // Add a count of two, one for each goroutine.
28 | wg.Add(2)
29 |
30 | // Create two goroutines.
31 | go incCounter(1)
32 | go incCounter(2)
33 |
34 | // Wait for the goroutines to finish.
35 | wg.Wait()
36 |
37 | // Display the final value.
38 | fmt.Println("Final Counter:", counter)
39 | }
40 |
41 | // incCounter increments the package level counter variable.
42 | func incCounter(id int) {
43 | for count := 0; count < 2; count++ {
44 | // Safely Add One To Counter.
45 | atomic.AddInt64(&counter, 1)
46 |
47 | // Yield the thread and be placed back in queue.
48 | runtime.Gosched()
49 | }
50 |
51 | // Tell main we are done.
52 | wg.Done()
53 | }
54 |
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/d2M0Q3mRnd
5 |
6 | // Declare three variables that are initialized to their zero value and three
7 | // declared with a literal value. Declare variables of type string, int and
8 | // bool. Display the values of those variables.
9 | //
10 | // Declare a new variable of type float32 and initialize the variable by
11 | // converting the literal value of Pi (3.14).
12 | package main
13 |
14 | import "fmt"
15 |
16 | // main is the entry point for the application.
17 | func main() {
18 | // Declare variables that are set to their zero value.
19 | var age int
20 | var name string
21 | var legal bool
22 |
23 | // Display the value of those variables.
24 | fmt.Println(age)
25 | fmt.Println(name)
26 | fmt.Println(legal)
27 |
28 | // Declare variables and initialize.
29 | // Using the short variable declaration operator.
30 | month := 10
31 | dayOfWeek := "Tuesday"
32 | happy := true
33 |
34 | // Display the value of those variables.
35 | fmt.Println(month)
36 | fmt.Println(dayOfWeek)
37 | fmt.Println(happy)
38 |
39 | // Perform a type conversion.
40 | pi := float32(3.14)
41 |
42 | // Display the value of that variable.
43 | fmt.Printf("%T [%v]\n", pi, pi)
44 | }
45 |
--------------------------------------------------------------------------------
/11-standard_library/01-logging/readme.md:
--------------------------------------------------------------------------------
1 | ## Logging - Standard Library
2 |
3 | Logging is an important part of every program. Logs are our eyes and history to what is happening inside the program as it runs. The standard library provides the log package to support the basic features of logging and the ability for you to extend and customize logging to fit your needs.
4 |
5 | ## Notes
6 |
7 | * Support for logging is already built into the standard library.
8 | * The log package can be easily extended to meet your logging needs.
9 |
10 | ## Links
11 |
12 | http://www.goinggo.net/2013/11/using-log-package-in-go.html
13 |
14 | ## Code Review
15 |
16 | [Use of log package](example1/example1.go) ([Go Playground](http://play.golang.org/p/xO5OuPOJef))
17 |
18 | [Customizing your own log](example2/example2.go) ([Go Playground](http://play.golang.org/p/008KxiH7Yj))
19 |
20 | ## Exercises
21 |
22 | ### Exercise 1
23 |
24 | Setup a new program to use the log package. Set the Prefix to your first name and on each log line show the date and long path for the code file.
25 |
26 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/9eVWni05Ma)) |
27 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/1-l_QmaSvy))
28 | ___
29 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/01-language_syntax/06-functions/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/XQS-twjrtl
5 |
6 | // From Spec:
7 | // a short variable declaration may redeclare variables provided they
8 | // were originally declared earlier in the same block with the same
9 | // type, and at least one of the non-blank variables is new.
10 |
11 | // Sample program to show some of the mechanics behind the
12 | // short variable declaration operator redeclares.
13 | package main
14 |
15 | import "fmt"
16 |
17 | // user is a struct type that declares user information.
18 | type user struct {
19 | id int
20 | name string
21 | }
22 |
23 | // main is the entry point for the application.
24 | func main() {
25 | // Declare the error variable.
26 | var err1 error
27 |
28 | // The short variable declaration operator will
29 | // declare u and redeclare err1.
30 | u, err1 := getUser()
31 | if err1 != nil {
32 | return
33 | }
34 |
35 | fmt.Println(u)
36 |
37 | // The short variable declaration operator will
38 | // redeclare u and declare err2.
39 | u, err2 := getUser()
40 | if err2 != nil {
41 | return
42 | }
43 |
44 | fmt.Println(u)
45 | }
46 |
47 | // getUser returns a pointer of type user.
48 | func getUser() (*user, error) {
49 | return &user{1432, "Betty"}, nil
50 | }
51 |
--------------------------------------------------------------------------------
/10-testing/exercises/exercise1/bench_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | /*
5 | http://golang.org/cmd/go/#hdr-Description_of_testing_flags
6 | go test -run=XXX -bench=.
7 | go test -run=XXX -bench=BenchmarkSprintf
8 | go test -run=XXX -bench=BenchmarkFormat
9 | go test -run=XXX -bench=BenchmarkAtoi
10 | */
11 |
12 | // Write three benchmark tests for converting an integer into a string. First using the
13 | // fmt.Sprintf function, then the strconv.FormatInt function and then strconv.Itoa.
14 | // Identify which function performs the best.
15 | package main
16 |
17 | import (
18 | "fmt"
19 | "strconv"
20 | "testing"
21 | )
22 |
23 | // BenchmarkSprintf provides performance numbers for the fmt.Sprintf function
24 | func BenchmarkSprintf(b *testing.B) {
25 | number := 10
26 |
27 | for i := 0; i < b.N; i++ {
28 | fmt.Sprintf("%d", number)
29 | }
30 | }
31 |
32 | // BenchmarkFormat provides performance numbers for the strconv.FormatInt function
33 | func BenchmarkFormat(b *testing.B) {
34 | number := int64(10)
35 |
36 | for i := 0; i < b.N; i++ {
37 | strconv.FormatInt(number, 10)
38 | }
39 | }
40 |
41 | // BenchmarkItoa provides performance numbers for the strconv.Itoa function
42 | func BenchmarkItoa(b *testing.B) {
43 | number := 10
44 |
45 | for i := 0; i < b.N; i++ {
46 | strconv.Itoa(number)
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/14-cli/03-flow/readme.md:
--------------------------------------------------------------------------------
1 | ## Conditional Control Flow
2 |
3 | Commands that complete successfully exit with status zero; all non-zero exit
4 | statuses indicate failure. Conventionally, a status of 1 is used as the generic
5 | program error status, and 2 indicates user error (such as invalid input or
6 | arguments), but any value in the range of 0-127 may be used. On many systems,
7 | statuses 128-255 have special meaning (such as signal reporting) and should not
8 | be set. The exit status of the last process in a pipeline is used as the status
9 | for the entire pipeline.
10 |
11 | The success or failure of a pipeline may be used to run additional pipelines:
12 |
13 | rm some-file && echo success || echo failure
14 |
15 | Pipelines chained in this way are known as "lists" and have left-to-right
16 | precedence, such that the above will always either echo success or failure, but
17 | never both. Most commonly, AND sequences are chained together so that a series
18 | of tasks can proceed only if every task before it was successful:
19 |
20 | task1 && task2 && task3
21 |
22 | If semicolons were used instead (or if each task were on its own line), then
23 | the tasks would run regardless of whether the previous tasks failed.
24 |
25 | ## Example
26 |
27 | [Setting exit status](example1/parent.go)
28 | ___
29 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
30 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/advanced/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://docs.google.com/document/d/1CxgUBPlx9iJzkz9JWkb6tIpTe5q32QDmz8l0BouG0Cw/view
5 |
6 | // http://play.golang.org/p/931Cw6uzsn
7 |
8 | // go build -gcflags -m
9 |
10 | // Sample program to show varaibles stay on or escape from the stack.
11 | package main
12 |
13 | import "fmt"
14 |
15 | // main is the entry point for the application.
16 | func main() {
17 | stayOnStack()
18 | escapeToHeap()
19 | }
20 |
21 | // stayOnStack shows how the variable does not escape.
22 | func stayOnStack() {
23 | // Declare a variable of type integer.
24 | var x int
25 |
26 | // Display the address of the variable.
27 | println("Stack Addr:", &x)
28 | }
29 |
30 | // escapeToHeap shows how the variable does escape.
31 | func escapeToHeap() {
32 | // Declare a variable of type integer.
33 | var x int
34 |
35 | // Display the address of the variable.
36 | fmt.Println("Heap Addr:", &x)
37 | }
38 |
39 | /*
40 | ./example1.go:20: can inline stayOnStack
41 | ./example1.go:15: inlining call to stayOnStack
42 | ./example1.go:31: moved to heap: x
43 | ./example1.go:34: &x escapes to heap
44 | ./example1.go:34: escapeToHeap ... argument does not escape
45 | ./example1.go:15: stayOnStack &x does not escape
46 | ./example1.go:25: stayOnStack &x does not escape
47 | */
48 |
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/yBFA-MDcMw
5 |
6 | // Fix the race condition in this program.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | "math/rand"
12 | "sync"
13 | "time"
14 | )
15 |
16 | // numbers maintains a set of random numbers.
17 | var numbers []int
18 |
19 | // wg is used to wait for the program to finish.
20 | var wg sync.WaitGroup
21 |
22 | // init is called prior to main.
23 | func init() {
24 | rand.Seed(time.Now().UnixNano())
25 | }
26 |
27 | // main is the entry point for all Go programs.
28 | func main() {
29 | // Add a count for each goroutine we will create.
30 | wg.Add(3)
31 |
32 | // Create three goroutines to generate random numbers.
33 | go random(10)
34 | go random(10)
35 | go random(10)
36 |
37 | // Wait for all the goroutines to finish.
38 | wg.Wait()
39 |
40 | // Display the set of random numbers.
41 | for i, number := range numbers {
42 | fmt.Println(i, number)
43 | }
44 | }
45 |
46 | // random generates random numbers and stores them into a slice.
47 | func random(amount int) {
48 | // Generate as many random numbers as specified.
49 | for i := 0; i < amount; i++ {
50 | n := rand.Intn(100)
51 | numbers = append(numbers, n)
52 | }
53 |
54 | // Tell main we are done.
55 | wg.Done()
56 | }
57 |
--------------------------------------------------------------------------------
/11-standard_library/01-logging/example1/example1.go:
--------------------------------------------------------------------------------
1 | // http://play.golang.org/p/xO5OuPOJef
2 |
3 | // Sample program to show how to use the log package
4 | // from the standard library.
5 | package main
6 |
7 | import (
8 | "log"
9 | "os"
10 | )
11 |
12 | // init is called before main.
13 | func init() {
14 | // Change the output device from the default
15 | // stderr to stdout.
16 | log.SetOutput(os.Stdout)
17 |
18 | // Set the prefix string for each log line.
19 | log.SetPrefix("TRACE: ")
20 |
21 | // Set the extra log info.
22 | setFlags()
23 | }
24 |
25 | // setFlags adds extra information on each log line.
26 | func setFlags() {
27 | /*
28 | Ldate // the date: 2009/01/23
29 | Ltime // the time: 01:23:23
30 | Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
31 | Llongfile // full file name and line number: /a/b/c/d.go:23
32 | Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
33 | LstdFlags // Ldate | Ltime // initial values for the standard logger
34 | */
35 |
36 | log.SetFlags(log.LstdFlags | log.Lshortfile)
37 | }
38 |
39 | // main is the entry point for the application.
40 | func main() {
41 | log.Println("main function started")
42 |
43 | names := []string{"Henry", "Lisa", "Bill", "Matt"}
44 | log.Printf("These are named %+v\n", names)
45 |
46 | log.Fatalln("Terminate Program")
47 |
48 | log.Println("main function ended")
49 | }
50 |
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/tnn-8hJPUd
5 |
6 | // Declare a struct type to maintain information about a user (name, email and age).
7 | // Create a value of this type, initialize with values and display each field.
8 | //
9 | // Declare and initialize an anonymous struct type with the same three fields. Display the value.
10 | package main
11 |
12 | import (
13 | "fmt"
14 | )
15 |
16 | // user represents a user in the system.
17 | type user struct {
18 | name string
19 | email string
20 | age int
21 | }
22 |
23 | // main is the entry point for the application.
24 | func main() {
25 | // Declare variable of type user and init using a struct literal.
26 | bill := user{
27 | name: "Bill",
28 | email: "bill@ardanstudios.com",
29 | age: 45,
30 | }
31 |
32 | // Display the field values.
33 | fmt.Println("Name", bill.name)
34 | fmt.Println("Email", bill.email)
35 | fmt.Println("Age", bill.age)
36 |
37 | // Declare a variable using an anonymous struct.
38 | ed := struct {
39 | name string
40 | email string
41 | age int
42 | }{
43 | name: "Ed",
44 | email: "ed@ardanstudios.com",
45 | age: 46,
46 | }
47 |
48 | // Display the field values.
49 | fmt.Println("Name", ed.name)
50 | fmt.Println("Email", ed.email)
51 | fmt.Println("Age", ed.age)
52 | }
53 |
--------------------------------------------------------------------------------
/09-concurrency_patterns/task/task.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Package task provides a pool of goroutines to perform tasks.
5 | package task
6 |
7 | import "sync"
8 |
9 | // Worker must be implemented by types that want to use
10 | // the run pool.
11 | type Worker interface {
12 | Work()
13 | }
14 |
15 | // Task provides a pool of goroutines that can execute any Worker
16 | // tasks that are submitted.
17 | type Task struct {
18 | work chan Worker
19 | wg sync.WaitGroup
20 | }
21 |
22 | // New creates a new work pool.
23 | func New(maxGoroutines int) *Task {
24 | t := Task{
25 | // Using an unbuffered channel because we want the
26 | // guarentee of knowing the work being submitted is
27 | // actually being worked on after the call to Run returns.
28 | work: make(chan Worker),
29 | }
30 |
31 | // The goroutines are the pool. So we could add code
32 | // to change the size of the pool later on.
33 |
34 | t.wg.Add(maxGoroutines)
35 | for i := 0; i < maxGoroutines; i++ {
36 | go func() {
37 | for w := range t.work {
38 | w.Work()
39 | }
40 | t.wg.Done()
41 | }()
42 | }
43 |
44 | return &t
45 | }
46 |
47 | // Do submits work to the pool.
48 | func (t *Task) Do(w Worker) {
49 | t.work <- w
50 | }
51 |
52 | // Shutdown waits for all the goroutines to shutdown.
53 | func (t *Task) Shutdown() {
54 | close(t.work)
55 | t.wg.Wait()
56 | }
57 |
--------------------------------------------------------------------------------
/11-standard_library/03-writers_readers/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/LY5P96Xrbl
5 |
6 | // https://gist.github.com/jmoiron/e9f72720cef51862b967#file-01-curl-go
7 | // Sample code provided by Jason Moiron
8 | //
9 | // ./example2 http://www.goinggo.net/feeds/posts/default
10 |
11 | // Sample program to show how to write a simple version of curl using
12 | // the io.Reader and io.Writer interface support.
13 | package main
14 |
15 | import (
16 | "fmt"
17 | "io"
18 | "net/http"
19 | "os"
20 | )
21 |
22 | // init is called before main.
23 | func init() {
24 | if len(os.Args) != 2 {
25 | fmt.Println("Usage: ./example2 ")
26 | os.Exit(2)
27 | }
28 | }
29 |
30 | // main is the entry point for the application.
31 | func main() {
32 | // resp here is a response, and resp.Body is an io.Reader
33 | resp, err := http.Get(os.Args[1])
34 | if err != nil {
35 | fmt.Println(err)
36 | return
37 | }
38 | // Close the ReadCloser when we're done with it.
39 | // We don't need to check the error, since
40 | // Close errors on Readers are meaningless.
41 | defer resp.Body.Close()
42 |
43 | // io.Copy(dst io.Writer, src io.Reader) (int64, error)
44 | // Copies from the Body to Stdout, returning any Read or Write error.
45 | _, err = io.Copy(os.Stdout, resp.Body)
46 | if err != nil {
47 | fmt.Println(err)
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/01-methods/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/zHePe-yTUw
5 |
6 | // Sample program to show how to declare methods against
7 | // a named type.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // duration is a named type that represents a duration
15 | // of time in Nanosecond.
16 | type duration int64
17 |
18 | const (
19 | nanosecond duration = 1
20 | microsecond = 1000 * nanosecond
21 | millisecond = 1000 * microsecond
22 | second = 1000 * millisecond
23 | minute = 60 * second
24 | hour = 60 * minute
25 | )
26 |
27 | // setHours sets the specified number of hours.
28 | func (d *duration) setHours(h float64) {
29 | *d = duration(h) * hour
30 | }
31 |
32 | // hours returns the duration as a floating point number of hours.
33 | func (d duration) hours() float64 {
34 | hour := d / hour
35 | nsec := d % hour
36 | return float64(hour) + float64(nsec)*(1e-9/60/60)
37 | }
38 |
39 | // main is the entry point for the application.
40 | func main() {
41 | // Declare a variable of type duration set to
42 | // its zero value.
43 | var dur duration
44 |
45 | // Change the value of dur to equal
46 | // five seconds.
47 | dur.setHours(5)
48 |
49 | // Display the new value of dur.
50 | fmt.Println("Hours:", dur.hours())
51 | }
52 |
--------------------------------------------------------------------------------
/11-standard_library/01-logging/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/9eVWni05Ma
5 |
6 | // Setup a new program to use the log package. Set the Prefix to your first name and on each log line show
7 | // the date and long path for the code file.
8 | package main
9 |
10 | // Add imports.
11 |
12 | // init is called before main.
13 | func init() {
14 | // Change the output device from the default stderr to stdout.
15 |
16 | // Set the prefix string for each log line.
17 |
18 | // Set the extra log info.
19 | }
20 |
21 | // setFlags adds extra information on each log line.
22 | func setFlags() {
23 | /*
24 | Ldate // the date: 2009/01/23
25 | Ltime // the time: 01:23:23
26 | Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
27 | Llongfile // full file name and line number: /a/b/c/d.go:23
28 | Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
29 | LstdFlags // Ldate | Ltime // initial values for the standard logger
30 | */
31 |
32 | // Set the flags.
33 | }
34 |
35 | // main is the entry point for the application.
36 | func main() {
37 | // Use the Println function.
38 |
39 | // Create a slice of strings and initialize with names.
40 | // Log the values of the slice.
41 |
42 | // Use the Fatalln function.
43 | }
44 |
--------------------------------------------------------------------------------
/12-reflection/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/OSeD9F_P46
5 |
6 | /*
7 | An interface is a reference type who's header is a two word value. The
8 | first word represents the type of the value and the second is the data
9 | itself.
10 |
11 | Something like this:
12 | type interface struct {
13 | Type uintptr // points to the type of the interface implementation
14 | Data uintptr // holds the data for the interface's receiver
15 | }
16 |
17 | interface{} represents the empty set of methods and is satisfied by any
18 | value at all, since any value has zero or more methods.
19 | */
20 |
21 | // Sample program to show how the empty interface works.
22 | package main
23 |
24 | import (
25 | "encoding/json"
26 | "fmt"
27 | )
28 |
29 | // User is a sample struct.
30 | type User struct {
31 | Name string
32 | Email string
33 | }
34 |
35 | // main is the entry point for the application.
36 | func main() {
37 | // Declare a variable of type User.
38 | user := User{
39 | Name: "Henry Ford",
40 | Email: "henry@ford.com",
41 | }
42 |
43 | fmt.Println(JSONString(&user))
44 | }
45 |
46 | // JSONString converts any value into a JSON string.
47 | func JSONString(value interface{}) string {
48 | data, err := json.MarshalIndent(value, "", " ")
49 | if err != nil {
50 | return ""
51 | }
52 |
53 | return string(data)
54 | }
55 |
--------------------------------------------------------------------------------
/02-array_slices_maps/01-arrays/readme.md:
--------------------------------------------------------------------------------
1 | ## Arrays - Arrays, Slices and Maps
2 |
3 | Arrays are a special data structure in Go that allow us to allocate contiguous blocks of fixed size memory. Arrays have some special features in Go related to how they are declared and viewed as types.
4 |
5 | ## Notes
6 |
7 | * Arrays are fixed length data structures that can't change.
8 | * Arrays of different sizes are considered to be of different types.
9 | * Memory is allocated as a contiguous block.
10 |
11 | ## Code Review
12 |
13 | [Declare, initialize and iterate](example1/example1.go) ([Go Playground](https://play.golang.org/p/DGr8Zp9L_w))
14 |
15 | [Different type arrays](example2/example2.go) ([Go Playground](http://play.golang.org/p/LVD43cYBNS))
16 |
17 | [Contiguous memory allocations](example3/example3.go) ([Go Playground](https://play.golang.org/p/s4BSgxz0Y3))
18 |
19 | ## Exercises
20 |
21 | ### Exercise 1
22 |
23 | Declare an array of 5 strings with each element initialized to its zero value. Declare a second array of 5 strings and initialize this array with literal string values. Assign the second array to the first and display the results of the first array.
24 |
25 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/ggjjRPzhAB)) |
26 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/Pa3mrTCcpB))
27 | ___
28 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/02-interfaces/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/eY2Ms-UF-t
5 |
6 | // Sample program to show how to use an interface in Go.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | )
12 |
13 | // notifier is an interface that defines notification
14 | // type behavior.
15 | type notifier interface {
16 | notify()
17 | }
18 |
19 | // user defines a user in the program.
20 | type user struct {
21 | name string
22 | email string
23 | }
24 |
25 | // notify implements the notifier interface with a pointer receiver.
26 | func (u *user) notify() {
27 | fmt.Printf("Sending User Email To %s<%s>\n",
28 | u.name,
29 | u.email)
30 | }
31 |
32 | // main is the entry point for the application.
33 | func main() {
34 | // Create a value of type User and send a notification.
35 | u := user{"Bill", "bill@email.com"}
36 |
37 | // Values of type user do not implement the interface because pointer
38 | // receivers don't belong to the method set of a value.
39 |
40 | sendNotification(u)
41 |
42 | // ./example1.go:40: cannot use u (type user) as type notifier in argument to sendNotification:
43 | // user does not implement notifier (notify method has pointer receiver)
44 | }
45 |
46 | // sendNotification accepts values that implement the notifier
47 | // interface and sends notifications.
48 | func sendNotification(n notifier) {
49 | n.notify()
50 | }
51 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/exercises/exercise2/exercise2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/oEtveMoO1s
5 |
6 | // Declare a struct type and create a value of this type. Declare a function
7 | // that can change the value of some field in this struct type. Display the
8 | // value before and after the call to your function.
9 | package main
10 |
11 | import "fmt"
12 |
13 | // user represents a user in the system.
14 | type user struct {
15 | name string
16 | email string
17 | accessLevel int
18 | }
19 |
20 | // main is the entry point for the application.
21 | func main() {
22 | // Create a variable of type user and initialize each field.
23 | bill := user{
24 | name: "Bill",
25 | email: "bill@ardanstudios.com",
26 | accessLevel: 1,
27 | }
28 |
29 | // Display the value of the accessLevel field.
30 | fmt.Println("access:", bill.accessLevel)
31 |
32 | // Share the bill variable with the accessLevel function
33 | // along with a value to update the accessLevel field with.
34 | accessLevel(&bill, 10)
35 |
36 | // Display the value of the accessLevel field again.
37 | fmt.Println("access:", bill.accessLevel)
38 | }
39 |
40 | // accessLevel changes the value of the users access level.
41 | func accessLevel(u *user, accessLevel int) {
42 | // Set of value of the accessLevel field to the value
43 | // that is passed in.
44 | u.accessLevel = accessLevel
45 | }
46 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/example4/example4.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/UzmwiMWDwd
5 |
6 | // Sample program to show how to grow a slice using the built-in function append
7 | // and how append grows the capacity of the underlying array.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare a nil slice of strings.
17 | var data []string
18 |
19 | // Capture the length and capacity of the slice.
20 | lastLen := len(data)
21 | lastCap := cap(data)
22 |
23 | // Append ~10k strings to the slice.
24 | for record := 1; record <= 10240; record++ {
25 | // Use the built-in function append to add to the slice.
26 | data = append(data, fmt.Sprintf("Rec: %d", record))
27 |
28 | // when the capacity of the slice changes, display the changes.
29 | if lastCap != cap(data) {
30 | // Calculate the percent of change.
31 | lenChg := float64(len(data)-lastLen) / float64(lastLen) * 100
32 | capChg := float64(cap(data)-lastCap) / float64(lastCap) * 100
33 |
34 | // Save the new values for length and capacity.
35 | lastLen = len(data)
36 | lastCap = cap(data)
37 |
38 | // Display the results.
39 | fmt.Printf("Addr[%p]\tIndex[%d]\t\tLen[%d - %2.f%%]\t\tCap[%d - %2.f%%]\n",
40 | &data[0],
41 | record,
42 | len(data),
43 | lenChg,
44 | cap(data),
45 | capChg)
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/00-slides/day_1_training.md:
--------------------------------------------------------------------------------
1 | ## Go Training - Day 1
2 | On this day we take our initial tour of the language. We learn about variables, types, data structures and OOP. We also explore what is idiomatic and how the language is very orthogonal. This includes following the community standards for coding and style.
3 |
4 | *Note: This material has been designed to be taught in a classroom environment. The code is well commented but missing some of the contextual concepts and ideas that will be covered in class.*
5 |
6 | #### Language Syntax
7 | [Variables](../01-language_syntax/01-variables/readme.md) |
8 | [Struct Types](../01-language_syntax/02-struct_types/readme.md) |
9 | [Pointers](../01-language_syntax/03-pointers/readme.md) |
10 | [Constants](../01-language_syntax/04-constants/readme.md) |
11 | [Type Conversions](../01-language_syntax/05-type_conversions/readme.md) |
12 | [Functions](../01-language_syntax/06-functions/readme.md)
13 |
14 | #### Arrays, Slices and Maps
15 | [Arrays](../02-array_slices_maps/01-arrays/readme.md) |
16 | [Slices](../02-array_slices_maps/02-slices/readme.md) |
17 | [Maps](../02-array_slices_maps/03-maps/readme.md)
18 |
19 | #### Methods, Interfaces and Embedding (OOP)
20 | [Methods](../03-methods_interfaces_embedding/01-methods/readme.md) |
21 | [Interfaces](../03-methods_interfaces_embedding/02-interfaces/readme.md) |
22 | [Embedding](../03-methods_interfaces_embedding/03-embedding/readme.md)
23 | ___
24 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/01-language_syntax/04-constants/readme.md:
--------------------------------------------------------------------------------
1 | ## Constants - Language Syntax
2 |
3 | Constants are a way to create a named identifier who's value can never change. They also provide an incredible amount of flexibility to the language. The way constants are implemented in Go is very unique.
4 |
5 | ## Notes
6 |
7 | * Constants are not variables.
8 | * They existing only at compilation.
9 | * Untyped constants can be implictly converted where typed constants and variables can't.
10 | * Think of untyped constants as having a Kind, not a Type.
11 |
12 | ## Links
13 |
14 | https://golang.org/ref/spec#Constants
15 |
16 | http://blog.golang.org/constants
17 |
18 | http://www.goinggo.net/2014/04/introduction-to-numeric-constants-in-go.html
19 |
20 | ## Code Review
21 |
22 | [Declare and inialize constants](example1/example1.go) ([Go Playground](http://play.golang.org/p/fkQx0inUJ3))
23 |
24 | [Parallel type system (Kind)](example2/example2.go) ([Go Playground](http://play.golang.org/p/ExxRWe6jUz))
25 |
26 | ## Exercises
27 |
28 | ### Exercise 1
29 |
30 | **Part A:** Declare an untyped and typed constant and display their values.
31 |
32 | **Part B:** Multiply two literal constants into a typed variable and display the value.
33 |
34 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/qG3-9yn5_6)) |
35 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/d2gkKxEftw))
36 | ___
37 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/01-language_syntax/06-functions/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/bYY-TRjfH0
5 |
6 | // Sample program to show how functions can return multiple values while using
7 | // named and struct types.
8 | package main
9 |
10 | import (
11 | "encoding/json"
12 | "fmt"
13 | )
14 |
15 | // user is a struct type that declares user information.
16 | type user struct {
17 | ID int
18 | Name string
19 | }
20 |
21 | // main is the entry point for the application.
22 | func main() {
23 | // Retrieve the user profile.
24 | u, err := retrieveUser("sally")
25 | if err != nil {
26 | fmt.Println(err)
27 | return
28 | }
29 |
30 | // Display the user profile.
31 | fmt.Printf("%+v\n", *u)
32 | }
33 |
34 | // retrieveUser retrieves the user document for the specified
35 | // user and returns a pointer to a user type value.
36 | func retrieveUser(name string) (*user, error) {
37 | // Make a call to get the user in a json response.
38 | r, err := getUser(name)
39 | if err != nil {
40 | return nil, err
41 | }
42 |
43 | // Unmarshal the json document into a value of
44 | // the user struct type.
45 | var u user
46 | err = json.Unmarshal([]byte(r), &u)
47 | return &u, err
48 | }
49 |
50 | // GetUser simulates a web call that returns a json
51 | // document for the specified user.
52 | func getUser(name string) (string, error) {
53 | response := `{"id":1432, "name":"sally"}`
54 | return response, nil
55 | }
56 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/03-embedding/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/BgEoThS7u9
5 |
6 | // Sample program to show how embedded types work with interfaces.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | )
12 |
13 | // notifier is an interface that defined notification
14 | // type behavior.
15 | type notifier interface {
16 | notify()
17 | }
18 |
19 | // user defines a user in the program.
20 | type user struct {
21 | name string
22 | email string
23 | }
24 |
25 | // notify implements a method that can be called via
26 | // a value of type user.
27 | func (u *user) notify() {
28 | fmt.Printf("Sending user email To %s<%s>\n",
29 | u.name,
30 | u.email)
31 | }
32 |
33 | // admin represents an admin user with privileges.
34 | type admin struct {
35 | user
36 | level string
37 | }
38 |
39 | // main is the entry point for the application.
40 | func main() {
41 | // Create an admin user.
42 | ad := admin{
43 | user: user{
44 | name: "john smith",
45 | email: "john@yahoo.com",
46 | },
47 | level: "super",
48 | }
49 |
50 | // Send the admin user a notification.
51 | // The embedded inner type's implementation of the
52 | // interface is "promoted" to the outer type.
53 | sendNotification(&ad)
54 | }
55 |
56 | // sendNotification accepts values that implement the notifier
57 | // interface and sends notifications.
58 | func sendNotification(n notifier) {
59 | n.notify()
60 | }
61 |
--------------------------------------------------------------------------------
/13-http/readme.md:
--------------------------------------------------------------------------------
1 | ## HTTP - API's
2 |
3 | The Go standard library provides all the critical building blocks for producing web sites and APIs.
4 |
5 | ## Notes
6 |
7 | * net/http provides an HTTP/1.1 compliant protocol implementation.
8 | * There is support for SSL/TLS.
9 | * Adding routing and middleware to your applications requires only a few simple patterns.
10 |
11 | ## Links
12 |
13 | https://golang.org/pkg/net/http/
14 |
15 | https://golang.org/doc/articles/wiki/
16 |
17 | https://github.com/bradfitz/http2
18 |
19 | https://github.com/interagent/http-api-design/blob/master/README.md
20 |
21 | http://www.restapitutorial.com/httpstatuscodes.html
22 |
23 | ## Code Review
24 |
25 | [Hello World Server](example1/main.go) ([Go Playground](https://play.golang.org/p/leTrm6v1yG))
26 |
27 | [1 Line File Server](example2/main.go) ([Go Playground](https://play.golang.org/p/Qmj_C5PEs1))
28 |
29 | [Request and Response Basics](example3/main.go) ([Go Playground](https://play.golang.org/p/-dhowrDOO4))
30 |
31 | ## Advanced Code Review
32 |
33 | [Web API](api)
34 | Sample code that provides best practices for building a RESTful API in Go. It leverages the standard library except for the router where a package named [httptreemux](https://github.com/dimfeld/httptreemux) is used. This router provides some nice conveniences such as handling verbs and access to parameters.
35 |
36 | ## Exercises
37 |
38 | ### Exercise 1
39 |
40 | TBD
41 | ___
42 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
43 |
--------------------------------------------------------------------------------
/01-language_syntax/03-pointers/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/VYqb11RiWr
5 |
6 | // Sample program to show the basic concept of using a pointer
7 | // to share data.
8 | package main
9 |
10 | import "fmt"
11 |
12 | // user represents a user in the system.
13 | type user struct {
14 | name string
15 | email string
16 | logins int
17 | }
18 |
19 | // main is the entry point for the application.
20 | func main() {
21 | // Declare and initialize a variable named bill of type user.
22 | bill := user{
23 | name: "Bill",
24 | email: "bill@ardanstudios.com",
25 | }
26 |
27 | //** We don't need to include all the fields when specifying field
28 | // names with a struct literal.
29 |
30 | // Pass the "address of" the bill value.
31 | display(&bill)
32 |
33 | // Pass the "address of" the logins field from within the bill value.
34 | increment(&bill.logins)
35 |
36 | // Pass the "address of" the bill value.
37 | display(&bill)
38 | }
39 |
40 | // increment declares logins as a pointer variable whose value is
41 | // always an address and points to values of type int.
42 | func increment(logins *int) {
43 | *logins++
44 | fmt.Printf("&logins[%p] logins[%p] *logins[%d]\n", &logins, logins, *logins)
45 | }
46 |
47 | // display declares u as user pointer variable whose value is always an address
48 | // and points to values of type user.
49 | func display(u *user) {
50 | fmt.Printf("%p\t%+v\n", u, *u)
51 | }
52 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/01-methods/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/AYsB78Dlxb
5 |
6 | // Sample program to show how to declare methods and how the Go
7 | // compiler supports them.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // user defines a user in the program.
15 | type user struct {
16 | name string
17 | email string
18 | }
19 |
20 | // notify implements a method with a value receiver.
21 | func (u user) notify() {
22 | fmt.Printf("Sending User Email To %s<%s>\n",
23 | u.name,
24 | u.email)
25 | }
26 |
27 | // changeEmail implements a method with a pointer receiver.
28 | func (u *user) changeEmail(email string) {
29 | u.email = email
30 | }
31 |
32 | // main is the entry point for the application.
33 | func main() {
34 | // Values of type user can be used to call methods
35 | // declared with a value receiver.
36 | bill := user{"Bill", "bill@email.com"}
37 | bill.notify()
38 |
39 | // Pointers of type user can also be used to call methods
40 | // declared with a value receiver.
41 | lisa := &user{"Lisa", "lisa@email.com"}
42 | lisa.notify()
43 |
44 | // Values of type user can be used to call methods
45 | // declared with a pointer receiver.
46 | bill.changeEmail("bill@gmail.com")
47 | bill.notify()
48 |
49 | // Pointers of type user can be used to call methods
50 | // declared with a pointer receiver.
51 | lisa.changeEmail("lisa@gmail.com")
52 | lisa.notify()
53 | }
54 |
--------------------------------------------------------------------------------
/12-reflection/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/lgMQHWpZul
5 |
6 | // Declare a struct type that represents a request for a customer invoice. Include a CustomerID and InvoiceID field. Define
7 | // tags that can be used to validate the request. Define tags that specify both the length and range for the ID to be valid.
8 | // Declare a function named validate that accepts values of any type and processes the tags. Display the resutls of the validation.
9 | package main
10 |
11 | // Add imports.
12 |
13 | // Declare a struct type named Customer. Add the fields CustomerID of type int
14 | // with the tag `length:"3" range:"100-300"`, and field InvoiceID of type int
15 | // with tag `length:"5" range:"60000-99999"`.
16 |
17 | // validate performs data validation on any struct type value.
18 | func validate( /* parameter */ ) {
19 | // Retrieve the value that the interface contains or points to.
20 |
21 | // Iterate over the fields of the struct value.
22 | {
23 | // Retrieve the field information.
24 |
25 | // Get the value as an int, string and the length.
26 |
27 | // Test the length of the value based on the tag setting.
28 |
29 | // Test the range of the value based on the tag setting.
30 | }
31 | }
32 |
33 | // main is the entry point for the application.
34 | func main() {
35 | // Declare a variable of type Customer and initialize it.
36 |
37 | // Validate the value and display the results.
38 | }
39 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/BSNAUj2pd-
5 |
6 | // Declare a nil slice of integers. Declare a nil slice of integers. Create a
7 | // loop that appends 10 values to the slice. Iterate over the slice and display
8 | // each value. Iterate over the slice and display each value.
9 | //
10 | // Declare a slice of five strings and initialize the slice with string literal
11 | // values. Display all the elements. Take a slice of index one and two
12 | // and display the index position and value of each element in the new slice.
13 | package main
14 |
15 | import "fmt"
16 |
17 | // main is the entry point for the application.
18 | func main() {
19 | // Declare a nil slice of integers.
20 | var numbers []int
21 |
22 | // Append numbers to the slice.
23 | for i := 0; i < 5; i++ {
24 | numbers = append(numbers, i*10)
25 | }
26 |
27 | // Display each value.
28 | for _, number := range numbers {
29 | fmt.Println(number)
30 | }
31 |
32 | // Declare a slice of strings.
33 | names := []string{"Bill", "Lisa", "Jim", "Cathy"}
34 |
35 | // Display each index position and name.
36 | for i, name := range names {
37 | fmt.Printf("Index: %d Name: %s\n", i, name)
38 | }
39 |
40 | // Take a slice of index 1 and 2.
41 | slice := names[1:3]
42 |
43 | // Display the value of the new slice.
44 | for i, name := range slice {
45 | fmt.Printf("Index: %d Name: %s\n", i, name)
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/m4PJ0FpSwX
5 |
6 | // The playground is actually a 64-bit env with 32-bit pointers
7 | // The os/arch combo is named nacl/amd64p32
8 |
9 | // Sample program to show how to declare variables.
10 | package main
11 |
12 | import "fmt"
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Declare variables that are set to their zero value.
17 | var a int
18 | var b string
19 | var c float64
20 | var d bool
21 |
22 | fmt.Printf("var a int \t %T [%v]\n", a, a)
23 | fmt.Printf("var b string \t %T [%v]\n", b, b)
24 | fmt.Printf("var c float64 \t %T [%v]\n", c, c)
25 | fmt.Printf("var d bool \t %T [%v]\n\n", d, d)
26 |
27 | // Declare variables and initialize.
28 | // Using the short variable declaration operator.
29 | aa := 10
30 | bb := "hello"
31 | cc := 3.14159
32 | dd := true
33 |
34 | fmt.Printf("aa := 10 \t %T [%v]\n", aa, aa)
35 | fmt.Printf("bb := \"hello\" \t %T [%v]\n", bb, bb)
36 | fmt.Printf("cc := 3.14159 \t %T [%v]\n", cc, cc)
37 | fmt.Printf("dd := true \t %T [%v]\n\n", dd, dd)
38 |
39 | // Specify type and perform a conversion.
40 | aaa := int32(10)
41 |
42 | fmt.Printf("aaa := int32(10) %T [%v]\n", aaa, aaa)
43 | }
44 |
45 | /*
46 | Zero Values:
47 |
48 | Type Initialized Value
49 | Boolean false
50 | Integer 0
51 | Floating Point 0
52 | Complex 0i
53 | String "" (empty string)
54 | Pointer nil
55 | */
56 |
--------------------------------------------------------------------------------
/10-testing/01-testing/example2/example2_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample test to show how to write a basic unit table test.
5 | package example2
6 |
7 | import (
8 | "net/http"
9 | "testing"
10 | )
11 |
12 | const succeed = "\u2713"
13 | const failed = "\u2717"
14 |
15 | // TestDownload validates the http Get function can download content and
16 | // handles different status conditions properly.
17 | func TestDownload(t *testing.T) {
18 | var urls = []struct {
19 | url string
20 | statusCode int
21 | }{
22 | {"http://www.goinggo.net/feeds/posts/default?alt=rss", http.StatusOK},
23 | {"http://rss.cnn.com/rss/cnn_topstorie.rss", http.StatusNotFound},
24 | }
25 |
26 | t.Log("Given the need to test downloading different content.")
27 | {
28 | for _, u := range urls {
29 | t.Logf("\tWhen checking \"%s\" for status code \"%d\"", u.url, u.statusCode)
30 | {
31 | resp, err := http.Get(u.url)
32 | if err != nil {
33 | t.Fatal("\t\tShould be able to make the Get call.",
34 | failed, err)
35 | }
36 | t.Log("\t\tShould be able to make the Get call.",
37 | succeed)
38 |
39 | defer resp.Body.Close()
40 |
41 | if resp.StatusCode == u.statusCode {
42 | t.Logf("\t\tShould receive a \"%d\" status code. %v",
43 | u.statusCode, succeed)
44 | } else {
45 | t.Errorf("\t\tShould receive a \"%d\" status code. %v %v",
46 | u.statusCode, failed, resp.StatusCode)
47 | }
48 | }
49 | }
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/02-array_slices_maps/03-maps/readme.md:
--------------------------------------------------------------------------------
1 | ## Maps - Arrays, Slices and Maps
2 |
3 | Maps provide a data structure that allow for the storage and management of key/value pair data.
4 |
5 | ## Notes
6 |
7 | * Maps provide a way to store and retrieve key/value pairs.
8 | * The map key must be a value that can be used in an assignment statement.
9 | * Iterating over a map is always random.
10 |
11 | ## Links
12 |
13 | http://blog.golang.org/go-maps-in-action
14 |
15 | http://www.goinggo.net/2013/12/macro-view-of-map-internals-in-go.html
16 |
17 | ## Code Review
18 |
19 | [Declare, initialize and iterate](example1/example1.go) ([Go Playground](http://play.golang.org/p/ZgPw0LU_Nv))
20 |
21 | [Map literal initialization](example2/example2.go) ([Go Playground](http://play.golang.org/p/hC1o26x7Q5))
22 |
23 | [Map key restrictions](example3/example3.go) ([Go Playground](http://play.golang.org/p/1JmxvWLAET))
24 |
25 | ## Advanced Code Review
26 |
27 | [Composing maps of maps](advanced/example1/example1.go) ([Go Playground](http://play.golang.org/p/pQsoB02pDl))
28 |
29 | ## Exercises
30 |
31 | ### Exercise 1
32 |
33 | Declare and make a map of integer values with a string as the key. Populate the map with five values and iterate over the map to display the key/value pairs.
34 |
35 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/-JBSUoux-v)) |
36 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/8K-IZgJFSg))
37 | ___
38 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/11-standard_library/03-writers_readers/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/KtrDN1BStt
5 |
6 | // Download any document from the web and display the content in
7 | // the terminal and write it to a file at the same time.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "io"
13 | "net/http"
14 | "os"
15 | )
16 |
17 | // main is the entry point for the application.
18 | func main() {
19 | // Retrieve the RSS feed for the blog.
20 | resp, err := http.Get("http://www.goinggo.net/feeds/posts/default")
21 | if err != nil {
22 | fmt.Println(err)
23 | return
24 | }
25 |
26 | // Arrange for the response Body to be Closed using defer.
27 | defer resp.Body.Close()
28 |
29 | // A slice of io.Writers we will write the file to.
30 | var writers []io.Writer
31 |
32 | // Send the document to stdout.
33 | writers = append(writers, os.Stdout)
34 |
35 | // Send the document to a file.
36 | file, err := os.Create("goinggo.rss")
37 | if err != nil {
38 | fmt.Println(err)
39 | return
40 | }
41 | defer file.Close()
42 |
43 | // Send the document to the file.
44 | writers = append(writers, file)
45 |
46 | // MultiWriter(io.Writer...) returns a single writer which multiplexes its
47 | // writes across all of the writers we pass in.
48 | dest := io.MultiWriter(writers...)
49 |
50 | // Write to dest the same way as before, copying from the Body.
51 | _, err = io.Copy(dest, resp.Body)
52 | if err != nil {
53 | fmt.Println(err)
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/cqsHoPD30n
5 |
6 | // Sample program to show how to create goroutines and
7 | // how the goroutine scheduler behaves with two contexts.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "runtime"
13 | "sync"
14 | )
15 |
16 | // main is the entry point for all Go programs.
17 | func main() {
18 | // wg is used to wait for the program to finish.
19 | // Add a count of two, one for each goroutine.
20 | var wg sync.WaitGroup
21 | wg.Add(2)
22 |
23 | // Allocate two contexts for the scheduler to use.
24 | runtime.GOMAXPROCS(2)
25 |
26 | fmt.Println("Start Goroutines")
27 |
28 | // Declare an anonymous function and create a goroutine.
29 | go func() {
30 | // Display the alphabet three times.
31 | for count := 0; count < 3; count++ {
32 | for rune := 'a'; rune < 'a'+26; rune++ {
33 | fmt.Printf("%c ", rune)
34 | }
35 | }
36 |
37 | // Tell main we are done.
38 | wg.Done()
39 | }()
40 |
41 | // Declare an anonymous function and create a goroutine.
42 | go func() {
43 | // Display the alphabet three times.
44 | for count := 0; count < 3; count++ {
45 | for rune := 'A'; rune < 'A'+26; rune++ {
46 | fmt.Printf("%c ", rune)
47 | }
48 | }
49 |
50 | // Tell main we are done.
51 | wg.Done()
52 | }()
53 |
54 | // Wait for the goroutines to finish.
55 | fmt.Println("Waiting To Finish")
56 | wg.Wait()
57 |
58 | fmt.Println("\nTerminating Program")
59 | }
60 |
--------------------------------------------------------------------------------
/11-standard_library/01-logging/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/1-l_QmaSvy
5 |
6 | // Setup a new program to use the log package. Set the Prefix to your first name and on each log line show
7 | // the date and long path for the code file.
8 | package main
9 |
10 | import (
11 | "log"
12 | "os"
13 | )
14 |
15 | // init is called before main.
16 | func init() {
17 | // Change the output device from the default stderr to stdout.
18 | log.SetOutput(os.Stdout)
19 |
20 | // Set the prefix string for each log line.
21 | log.SetPrefix("BILL: ")
22 |
23 | // Set the extra log info.
24 | setFlags()
25 | }
26 |
27 | // setFlags adds extra information on each log line.
28 | func setFlags() {
29 | /*
30 | Ldate // the date: 2009/01/23
31 | Ltime // the time: 01:23:23
32 | Lmicroseconds // microsecond resolution: 01:23:23.123123. assumes Ltime.
33 | Llongfile // full file name and line number: /a/b/c/d.go:23
34 | Lshortfile // final file name element and line number: d.go:23. overrides Llongfile
35 | LstdFlags // Ldate | Ltime // initial values for the standard logger
36 | */
37 |
38 | log.SetFlags(log.Ldate | log.Llongfile)
39 | }
40 |
41 | // main is the entry point for the application.
42 | func main() {
43 | log.Println("main function started")
44 |
45 | names := []string{"Henry", "Lisa", "Bill", "Matt"}
46 | log.Printf("These are named %+v\n", names)
47 |
48 | log.Fatalln("Terminate Program")
49 | }
50 |
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/wFTNvVoBpz
5 |
6 | // Answer for exercise 1 of Race Conditions.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | "math/rand"
12 | "sync"
13 | "time"
14 | )
15 |
16 | // numbers maintains a set of random numbers.
17 | var numbers []int
18 |
19 | // wg is used to wait for the program to finish.
20 | var wg sync.WaitGroup
21 |
22 | // mutex will help protect the slice.
23 | var mutex sync.Mutex
24 |
25 | // init is called prior to main.
26 | func init() {
27 | rand.Seed(time.Now().UnixNano())
28 | }
29 |
30 | // main is the entry point for all Go programs.
31 | func main() {
32 | // Add a count for each goroutine we will create.
33 | wg.Add(3)
34 |
35 | // Create three goroutines to generate random numbers.
36 | go random(10)
37 | go random(10)
38 | go random(10)
39 |
40 | // Wait for all the goroutines to finish.
41 | wg.Wait()
42 |
43 | // Display the set of random numbers.
44 | for i, number := range numbers {
45 | fmt.Println(i, number)
46 | }
47 | }
48 |
49 | // random generates random numbers and stores them into a slice.
50 | func random(amount int) {
51 | // Generate as many random numbers as specified.
52 | for i := 0; i < amount; i++ {
53 | n := rand.Intn(100)
54 |
55 | // Protect this append to keep access safe.
56 | mutex.Lock()
57 | {
58 | numbers = append(numbers, n)
59 | }
60 | mutex.Unlock()
61 | }
62 |
63 | // Tell main we are done.
64 | wg.Done()
65 | }
66 |
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/LI0TEB6PMf
5 |
6 | // Sample program to show how to create goroutines and
7 | // how the scheduler behaves.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "sync"
13 | )
14 |
15 | // wg is used to wait for the program to finish.
16 | var wg sync.WaitGroup
17 |
18 | // main is the entry point for all Go programs.
19 | func main() {
20 | // Add a count of two, one for each goroutine.
21 | wg.Add(2)
22 |
23 | fmt.Println("Start Goroutines")
24 |
25 | // Create a goroutine from the lowercase function.
26 | go lowercase()
27 |
28 | // Create a goroutine from the uppercase function.
29 | go uppercase()
30 |
31 | // Wait for the goroutines to finish.
32 | fmt.Println("Waiting To Finish")
33 | wg.Wait()
34 |
35 | fmt.Println("\nTerminating Program")
36 | }
37 |
38 | // lowercase displays the set of lowercase letters three times.
39 | func lowercase() {
40 | // Display the alphabet three times
41 | for count := 0; count < 3; count++ {
42 | for rune := 'a'; rune < 'a'+26; rune++ {
43 | fmt.Printf("%c ", rune)
44 | }
45 | }
46 |
47 | // Tell main we are done.
48 | wg.Done()
49 | }
50 |
51 | // uppercase displays the set of uppercase letters three times.
52 | func uppercase() {
53 | // Display the alphabet three times
54 | for count := 0; count < 3; count++ {
55 | for rune := 'A'; rune < 'A'+26; rune++ {
56 | fmt.Printf("%c ", rune)
57 | }
58 | }
59 |
60 | // Tell main we are done.
61 | wg.Done()
62 | }
63 |
--------------------------------------------------------------------------------
/09-concurrency_patterns/task/main/main.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // This sample program demonstrates how to use the work package
5 | // to use a pool of goroutines to get work done.
6 | package main
7 |
8 | import (
9 | "log"
10 | "sync"
11 | "time"
12 |
13 | "github.com/gobridge/gotraining/09-concurrency_patterns/task"
14 | )
15 |
16 | // names provides a set of names to display.
17 | var names = []string{
18 | "steve",
19 | "bob",
20 | "mary",
21 | "therese",
22 | "jason",
23 | }
24 |
25 | // namePrinter provides special support for printing names.
26 | type namePrinter struct {
27 | name string
28 | }
29 |
30 | // Work implements the Worker interface.
31 | func (m namePrinter) Work() {
32 | log.Println(m.name)
33 | time.Sleep(3 * time.Second)
34 | }
35 |
36 | // main is the entry point for all Go programs.
37 | func main() {
38 | // Create a task pool with 4 goroutines.
39 | t := task.New(10)
40 |
41 | var wg sync.WaitGroup
42 | wg.Add(10 * len(names))
43 |
44 | for i := 0; i < 10; i++ {
45 | // Iterate over the slice of names.
46 | for _, name := range names {
47 | // Create a namePrinter and provide the
48 | // specific name.
49 | np := namePrinter{
50 | name: name,
51 | }
52 |
53 | go func() {
54 | // Submit the task to be worked on. When Do
55 | // returns, we know it is being handled.
56 | t.Do(np)
57 | wg.Done()
58 | }()
59 | }
60 | }
61 |
62 | wg.Wait()
63 |
64 | // Shutdown the task pool and wait for all existing work
65 | // to be completed.
66 | t.Shutdown()
67 | }
68 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/advanced/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/dJk2eycWhH
5 |
6 | // Sample program to show how to use a third index slice.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | )
12 |
13 | // main is the entry point for the application.
14 | func main() {
15 | // Create a slice of strings with different types of fruit.
16 | slice := []string{"Apple", "Orange", "Banana", "Grape", "Plum"}
17 | inspectSlice(slice)
18 |
19 | // Take a slice of slice. We want just index 2
20 | // takeOne[0] = "Banana"
21 | // Length: 3 - 2
22 | // Capacity: 5 - 2
23 | takeOne := slice[2:3]
24 | inspectSlice(takeOne)
25 |
26 | // For slice[ i : j : k ] the
27 | // Length: j - i
28 | // Capacity: k - i
29 |
30 | // Take a slice of just index 2 with a length and capacity of 1
31 | // takeOneCapOne[0] = "Banana"
32 | // Length: 3 - 2
33 | // Capacity: 3 - 2
34 | takeOneCapOne := slice[2:3:3] // Use the third index position to
35 | inspectSlice(takeOneCapOne) // set the capacity to 1.
36 |
37 | // Append a new element which will create a new
38 | // underlying array to increase capacity.
39 | takeOneCapOne = append(takeOneCapOne, "Kiwi")
40 | inspectSlice(takeOneCapOne)
41 | }
42 |
43 | // inspectSlice exposes the slice header for review.
44 | func inspectSlice(slice []string) {
45 | fmt.Printf("Length[%d] Capacity[%d]\n", len(slice), cap(slice))
46 | for index, value := range slice {
47 | fmt.Printf("[%d] %p %s\n",
48 | index,
49 | &slice[index],
50 | value)
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/07-error_handling/exercises/template2/template2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/x6UimVQMMQ
5 |
6 | // Create a custom error type called appError that contains three fields, Err error,
7 | // Message string and Code int. Implement the error interface providing your own message
8 | // using these three fields. Write a function called checkFlag that accepts a bool value.
9 | // If the value is false, return a pointer of your custom error type initialized as you like.
10 | // If the value is true, return a default error. Write a main function to call the
11 | // checkFlag function and check the error for the concrete type.
12 | package main
13 |
14 | // Add imports.
15 |
16 | // Declare a struct type named appError with three fields, Err of type error,
17 | // Message of type string and Code of type int.
18 |
19 | // Declare a method for the appError struct type that implements the
20 | // error interface.
21 |
22 | // Declare a function named checkFlag that accepts a boolean value and
23 | // returns an error interface value.
24 | func checkFlag( /* parameter */ ) /* return arg */ {
25 | // If the parameter is false return an appError.
26 |
27 | // Return a default error.
28 | }
29 |
30 | // main is the entry point for the application.
31 | func main() {
32 | // Call the checkFlag function to simulate an error of the
33 | // concrete type.
34 |
35 | // Check the concrete type and handle appropriately.
36 | switch e := err.(type) {
37 | // Apply the case for the default error type.
38 |
39 | // Apply the default case.
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/10-testing/03-caching/caching.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/GQQXh3cf15
5 |
6 | // package caching provides code to show why CPU caches matter and the way
7 | // the hardware caches memory affects performance.
8 | package caching
9 |
10 | import "fmt"
11 |
12 | const cols = 64
13 |
14 | // Set the size of each row to be 4k.
15 | //const rows = 4 * 1024
16 |
17 | // Set the size of each row to be 64k.
18 | const rows = 64 * 1024
19 |
20 | // matrix represents a set of columns that each exist on
21 | // their own cache line.
22 | var matrix [cols][rows]byte
23 |
24 | // init sets ~13% of the matrix to 0XFF.
25 | func init() {
26 | var ctr int
27 | for col := 0; col < cols; col++ {
28 | for row := 0; row < rows; row++ {
29 | if row%8 == 0 {
30 | matrix[col][row] = 0xFF
31 | ctr++
32 | }
33 | }
34 | }
35 |
36 | fmt.Println(ctr, "Elements set out of", cols*rows)
37 | }
38 |
39 | // rowTraverse traverses the matrix linearly by each column for each row.
40 | func rowTraverse() int {
41 | var ctr int
42 |
43 | for col := 0; col < cols; col++ {
44 | for row := 0; row < rows; row++ {
45 | if matrix[col][row] == 0xFF {
46 | ctr++
47 | }
48 | }
49 | }
50 |
51 | return ctr
52 | }
53 |
54 | // colTraverse traverses the matrix linearly by each row for each column.
55 | func colTraverse() int {
56 | var ctr int
57 |
58 | for row := 0; row < rows; row++ {
59 | for col := 0; col < cols; col++ {
60 | if matrix[col][row] == 0xFF {
61 | ctr++
62 | }
63 | }
64 | }
65 |
66 | return ctr
67 | }
68 |
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/qifiyxrX1R
5 |
6 | // go build -race
7 |
8 | // Sample program to show how to use the atomic package functions
9 | // Store and Load to provide safe access to numeric types.
10 | package main
11 |
12 | import (
13 | "fmt"
14 | "sync"
15 | "sync/atomic"
16 | "time"
17 | )
18 |
19 | // shutdown is a flag to alert running goroutines to shutdown.
20 | var shutdown int64
21 |
22 | // wg is used to wait for the program to finish.
23 | var wg sync.WaitGroup
24 |
25 | // main is the entry point for all Go programs.
26 | func main() {
27 | // Add a count of two, one for each goroutine.
28 | wg.Add(2)
29 |
30 | // Create two goroutines.
31 | go doWork("A")
32 | go doWork("B")
33 |
34 | // Give the goroutines time to run so we can see
35 | // the shutdown flag work.
36 | time.Sleep(time.Second)
37 |
38 | // Safely flag it is time to shutdown.
39 | fmt.Println("Shutdown Now")
40 | atomic.StoreInt64(&shutdown, 1)
41 |
42 | // Wait for the goroutines to finish.
43 | wg.Wait()
44 | }
45 |
46 | // doWork simulates a goroutine performing work and
47 | // checking the Shutdown flag to terminate early.
48 | func doWork(name string) {
49 | for {
50 | fmt.Printf("Doing %s Work\n", name)
51 | time.Sleep(250 * time.Millisecond)
52 |
53 | // Do we need to shutdown.
54 | if atomic.LoadInt64(&shutdown) == 1 {
55 | fmt.Printf("Shutting %s Down\n", name)
56 | break
57 | }
58 | }
59 |
60 | // Tell main we are done.
61 | wg.Done()
62 | }
63 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/02-interfaces/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/Lo1ucf1e9d
5 |
6 | // Sample program to show how polymorphic behavior with interfaces.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | )
12 |
13 | // notifier is an interface that defines notification
14 | // type behavior.
15 | type notifier interface {
16 | notify()
17 | }
18 |
19 | // user defines a user in the program.
20 | type user struct {
21 | name string
22 | email string
23 | }
24 |
25 | // notify implements the notifier interface with a pointer receiver.
26 | func (u *user) notify() {
27 | fmt.Printf("Sending user Email To %s<%s>\n",
28 | u.name,
29 | u.email)
30 | }
31 |
32 | // admin defines a admin in the program.
33 | type admin struct {
34 | name string
35 | email string
36 | }
37 |
38 | // notify implements the notifier interface with a pointer receiver.
39 | func (a *admin) notify() {
40 | fmt.Printf("Sending admin Email To %s<%s>\n",
41 | a.name,
42 | a.email)
43 | }
44 |
45 | // main is the entry point for the application.
46 | func main() {
47 | // Create two values one of type user and one of type admin.
48 | bill := user{"Bill", "bill@email.com"}
49 | jill := admin{"Jill", "jill@email.com"}
50 |
51 | // Pass a pointer of the values to support the interface.
52 | sendNotification(&bill)
53 | sendNotification(&jill)
54 | }
55 |
56 | // sendNotification accepts values that implement the notifier
57 | // interface and sends notifications.
58 | func sendNotification(n notifier) {
59 | n.notify()
60 | }
61 |
--------------------------------------------------------------------------------
/01-language_syntax/04-constants/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/fkQx0inUJ3
5 |
6 | // Sample program to show how to declare constants and their
7 | // implementation in Go.
8 | package main
9 |
10 | // main is the entry point for the application.
11 | func main() {
12 | // Constants live within the compiler.
13 | // They have a parallel type system.
14 | // Compiler can perform implicit conversions of untyped constants.
15 |
16 | // Untyped Constants.
17 | const ui = 12345 // kind: integer
18 | const uf = 3.141592 // kind: floating-point
19 |
20 | // Typed Constants still use the constant type system but their precision
21 | // is restricted.
22 | const ti int = 12345 // type: int64
23 | const tf float64 = 3.141592 // type: float64
24 |
25 | // ./constants.go:14: constant 1000 overflows uint8
26 | // const myUint8 uint8 = 1000
27 |
28 | // Constant arithmetic supports different kinds.
29 | // Kind Promotion is used to determine kind in these scenarios.
30 | // Variable answer will be implicitly converted to type floating point.
31 | var answer = 3 * 0.333 // KindInt(3) * KindFloat(0.333)
32 |
33 | // Variable third will be of kind floating point.
34 | const third = 1 / 3.0 // KindInt(1) / KindFloat(3.0)
35 |
36 | // Variable zero will be of kind integer.
37 | const zero = 1 / 3 // KindInt(1) / KindInt(3)
38 |
39 | // This is an example of constant arithmetic between typed and
40 | // untyped constants. Must have like types to perform math.
41 | const one int8 = 1
42 | const two = 2 * one // KindInt(2) * int8(1)
43 | }
44 |
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/exercises/template2/template2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/vc6c1-M2EB
5 |
6 | // Write a problem that uses a buffered channel to maintain a buffer
7 | // of four strings. In main, send the strings 'A', 'B', 'C' and 'D'
8 | // into the channel. Then create 20 goroutines that receive a string
9 | // from the channel, display the value and then send the string back
10 | // into the channel. Once each goroutine is done performing that task,
11 | // allow the goroutine to terminate.
12 | package main
13 |
14 | // Add Imports.
15 |
16 | // Declare a constant and set the value for the number of goroutines.
17 |
18 | // Declare a constant and set the value for the number of buffers.
19 |
20 | // Declare a wait group.
21 |
22 | // Declare a buffered channel of type string and initialize it based on
23 | // the constant you declared above.
24 |
25 | // Declare a function for the goroutine that will process work
26 | // from the buffered channel.
27 | func worker(worker int) {
28 | // Receive a string from the channel.
29 |
30 | // Display the string.
31 |
32 | // Send the string back into the channel.
33 |
34 | // Tell main this goroutine is done.
35 | }
36 |
37 | // main is the entry point for all Go programs.
38 | func main() {
39 | // Increment the wait group for the number of
40 | // goroutines based on the value of the constant.
41 |
42 | // Create the number of goroutines based on the
43 | // value of the constant.
44 |
45 | // Add strings in the buffered channel.
46 |
47 | // Wait for all the work to get done.
48 | }
49 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/01-methods/advanced/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/MNI1jR8Ets
5 |
6 | // Sample program to show how to declare function variables.
7 | package main
8 |
9 | import "fmt"
10 |
11 | // data is a struct to bind methods to.
12 | type data struct {
13 | name string
14 | age int
15 | }
16 |
17 | // displayName provides a pretty print view of the name.
18 | func (d data) displayName() {
19 | fmt.Println("My Name Is: ", d.name)
20 | }
21 |
22 | // setAge sets the age and displays the value.
23 | func (d *data) setAge(age int) {
24 | d.age = age
25 | fmt.Println("Set Age: ", d.age)
26 | }
27 |
28 | // main is the entry point for the application.
29 | func main() {
30 | // Declare a variable of type data.
31 | d := data{
32 | name: "Bill",
33 | }
34 |
35 | // Declare a function variable for the method
36 | // bound to the d variable.
37 | f1 := d.displayName
38 |
39 | // Call the method via the variable.
40 | f1()
41 |
42 | // Declare a function variable for the function
43 | // bound to the package.
44 | f2 := data.displayName
45 |
46 | // Call the function passing the receiver.
47 | f2(d)
48 |
49 | // Declare a function variable for the method
50 | // bound to the d variable.
51 | f3 := d.setAge
52 |
53 | // Call the method via the variable passing the parameter.
54 | f3(45)
55 |
56 | // Declare a function variable for the function
57 | // bound to the package. The receiver is a pointer.
58 | f4 := (*data).setAge
59 |
60 | // Call the function passing the receiver and the parameter.
61 | f4(&d, 55)
62 | }
63 |
--------------------------------------------------------------------------------
/01-language_syntax/01-variables/readme.md:
--------------------------------------------------------------------------------
1 | ## Variables - Language Syntax
2 |
3 | Variables are at the heart of the language and provide the ability to read from and write to memory. In Go, access to memory is type safe. This means the compiler takes type seriously and will not allow us to use variables outside the scope of how they are declared.
4 |
5 | ## Notes
6 |
7 | * When variables are being declared to their zero value, use the keyword var.
8 | * When variables are being declared and initialized, use the short variable declaration operator.
9 | * Escape analysis is used to determine when a value escapes to the heap.
10 |
11 | ## Links
12 |
13 | [Built-In Types](http://golang.org/ref/spec#Boolean_types)
14 |
15 | https://golang.org/doc/effective_go.html#variables
16 |
17 | http://www.goinggo.net/2013/08/gustavos-ieee-754-brain-teaser.html
18 |
19 | ## Code Review
20 |
21 | [Declare and initialize variables](example1/example1.go) ([Go Playground](http://play.golang.org/p/6w6hBNE75a))
22 |
23 | ## Exercises
24 |
25 | ### Exercise 1
26 |
27 | **Part A:** Declare three variables that are initialized to their zero value and three declared with a literal value. Declare variables of type string, int and bool. Display the values of those variables.
28 |
29 | **Part B:** Declare a new variable of type float32 and initialize the variable by converting the literal value of Pi (3.14).
30 |
31 | [Template](exercises/template1/template1.go) ([Go Playground](https://play.golang.org/p/1xUWjHMB3I)) |
32 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](https://play.golang.org/p/d2M0Q3mRnd))
33 | ___
34 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
35 |
--------------------------------------------------------------------------------
/02-array_slices_maps/02-slices/example3/example3.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/nZnkHsGj_P
5 |
6 | // Sample program to show how to takes slices of slices to create different
7 | // views of and make changes to the underlying array.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Create a slice with a length of 5 elements and a capacity of 8.
17 | slice1 := make([]string, 5, 8)
18 | slice1[0] = "Apple"
19 | slice1[1] = "Orange"
20 | slice1[2] = "Banana"
21 | slice1[3] = "Grape"
22 | slice1[4] = "Plum"
23 |
24 | inspectSlice(slice1)
25 |
26 | // For slice[i:j] with an underlying array of capacity k
27 | // Final Length: j - i
28 | // Final Capacity: k - i
29 |
30 | // Take a slice of slice1. We want just indexes 2 and 3.
31 | // slice2[0] = "Banana"
32 | // slice2[1] = "Grape"
33 | // Length: 4 - 2
34 | // Capacity: 8 - 2
35 |
36 | // Parameters are [starting_index : (starting_index + length)
37 | slice2 := slice1[2:4]
38 | inspectSlice(slice2)
39 |
40 | fmt.Println("*************************")
41 |
42 | // Change the value of the index 0 of slice3.
43 | slice2[0] = "CHANGED"
44 |
45 | // Display the change across all existing slices.
46 | inspectSlice(slice1)
47 | inspectSlice(slice2)
48 | }
49 |
50 | // inspectSlice exposes the slice header for review.
51 | func inspectSlice(slice []string) {
52 | fmt.Printf("Length[%d] Capacity[%d]\n", len(slice), cap(slice))
53 | for i, v := range slice {
54 | fmt.Printf("[%d] %p %s\n",
55 | i,
56 | &slice[i],
57 | v)
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/11-standard_library/02-encoding/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/Huf8jEDUJO
5 |
6 | // Create a file with an array of JSON documents that contain a user name and email address. Declare a struct
7 | // type that maps to the JSON document. Using the json package, read the file and create a slice of this struct
8 | // type. Display the slice.
9 | //
10 | // Marshal the slice into pretty print strings and display each element.
11 | package main
12 |
13 | import (
14 | "encoding/json"
15 | "fmt"
16 | "os"
17 | )
18 |
19 | // user is the data we need to unmarshal and marshal.
20 | type user struct {
21 | Name string `json:"name"`
22 | Email string `json:"email"`
23 | }
24 |
25 | // main is the entry point for the application.
26 | func main() {
27 | // Open the file.
28 | file, err := os.Open("data.json")
29 | if err != nil {
30 | fmt.Println("Open File", err)
31 | return
32 | }
33 |
34 | // Schedule the file to be closed once
35 | // the function returns.
36 | defer file.Close()
37 |
38 | // Decode the file into this slice.
39 | var users []user
40 | err = json.NewDecoder(file).Decode(&users)
41 | if err != nil {
42 | fmt.Println("Decode File", err)
43 | return
44 | }
45 |
46 | // Iterate over the slice and display
47 | // each user.
48 | for _, u := range users {
49 | fmt.Printf("%+v\n", u)
50 | }
51 |
52 | uData, err := json.MarshalIndent(&users, "", " ")
53 | if err != nil {
54 | fmt.Println("MarshalIndent", err)
55 | return
56 | }
57 |
58 | // Convert the byte slice to a string and display.
59 | fmt.Println(string(uData))
60 | }
61 |
--------------------------------------------------------------------------------
/08-concurrency_channels/01-goroutines/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/mB4QslSNoA
5 |
6 | // Create a program that declares two anonymous functions. Once that counts up to
7 | // 100 from 0 and one that counts down to 0 from 100. Display each number with an
8 | // unique identifier for each goroutine. Then create goroutines from these functions
9 | // and don't let main return until the goroutines complete.
10 | //
11 | // Run the program in parallel.
12 | package main
13 |
14 | import (
15 | "fmt"
16 | "sync"
17 | )
18 |
19 | // main is the entry point for all Go programs.
20 | func main() {
21 | // wg is used to wait for the program to finish.
22 | // Add a count of two, one for each goroutine.
23 | var wg sync.WaitGroup
24 | wg.Add(2)
25 |
26 | // Allocate two contexts for the scheduler to use.
27 | // runtime.GOMAXPROCS(2)
28 |
29 | fmt.Println("Start Goroutines")
30 |
31 | // Declare an anonymous function and create a goroutine.
32 | go func() {
33 | // Count down from 100 to 0.
34 | for count := 100; count >= 0; count-- {
35 | fmt.Printf("[A:%d]\n", count)
36 | }
37 |
38 | // Tell main we are done.
39 | wg.Done()
40 | }()
41 |
42 | // Declare an anonymous function and create a goroutine.
43 | go func() {
44 | // Count up from 0 to 100.
45 | for count := 0; count < 100; count++ {
46 | fmt.Printf("[B:%d]\n", count)
47 | }
48 |
49 | // Tell main we are done.
50 | wg.Done()
51 | }()
52 |
53 | // Wait for the goroutines to finish.
54 | fmt.Println("Waiting To Finish")
55 | wg.Wait()
56 |
57 | fmt.Println("\nTerminating Program")
58 | }
59 |
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/G7O-DnJrEA
5 |
6 | // Write a program where two goroutines pass an integer back and forth
7 | // ten times. Display when each goroutine receives the integer. Increment
8 | // the integer with each pass. Once the integer equals ten, terminate
9 | // the program cleanly.
10 | package main
11 |
12 | // Add imports.
13 |
14 | // Declare a wait group variable.
15 |
16 | // Declare a function for the goroutine. Pass in a name for the
17 | // routine and a channel of type int used to share the value back and forth.
18 | func goroutine( /* parameters */ ) {
19 | for {
20 | // Receive on the channel, waiting for the integer.
21 |
22 | // Check if the channel is closed.
23 | {
24 | // Call done on the waitgroup.
25 | // Display the goroutine is finished and return.
26 | }
27 |
28 | // Display the integer value received.
29 |
30 | // Check is the value from the channel is 10.
31 | {
32 | // Close the channel.
33 | // Call done on the waitgroup.
34 | // Display the goroutine is finished and return.
35 | }
36 |
37 | // Increment the value by one and send in back through
38 | // the channel.
39 | }
40 | }
41 |
42 | // main is the entry point for all Go programs.
43 | func main() {
44 | // Declare and initialize an unbuffered channel
45 | // of type int.
46 |
47 | // Increment the wait group for each goroutine
48 | // to be created.
49 |
50 | // Create the two goroutines.
51 |
52 | // Send the initial integer value into the channel.
53 |
54 | // Wait for all the goroutines to finish.
55 | }
56 |
--------------------------------------------------------------------------------
/12-reflection/readme.md:
--------------------------------------------------------------------------------
1 | ## Reflection
2 |
3 | Reflection is the ability to inspect a value to derive type or other meta-data. Reflection can give our program incredible flexibility to work with data of different types or create values on the fly. Reflection is critical for the encoding and decoding of data.
4 |
5 | ## Notes
6 |
7 | * The reflection package allows us to inspect our types.
8 | * We can add "tags" to our struct fields to store and use meta-data.
9 | * Encoding package leverages reflection and we can as well.
10 |
11 | ## Links
12 |
13 | http://blog.golang.org/laws-of-reflection
14 |
15 | ## Code Review
16 |
17 | [Empty Interface](example1/example1.go) ([Go Playground](http://play.golang.org/p/OSeD9F_P46))
18 |
19 | [Reflect struct types with tags](example2/example2.go) ([Go Playground](http://play.golang.org/p/y0WyYezH05))
20 |
21 | ## Advanced Code Review
22 |
23 | [Decoding function for integers](example3/example3.go) ([Go Playground](http://play.golang.org/p/bWQ6hiVECQ))
24 |
25 | ## Exercises
26 |
27 | ### Exercise 1
28 | Declare a struct type that represents a request for a customer invoice. Include a CustomerID and InvoiceID field. Define tags that can be used to validate the request. Define tags that specify both the length and range for the ID to be valid. Declare a function named validate that accepts values of any type and processes the tags. Display the results of the validation.
29 |
30 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/lgMQHWpZul)) |
31 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/xy-wyPrsjz))
32 | ___
33 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
34 |
--------------------------------------------------------------------------------
/01-language_syntax/02-struct_types/readme.md:
--------------------------------------------------------------------------------
1 | ## Struct Types - Language Syntax
2 |
3 | Struct types are a way of creating complex types that group fields of data together. They are a great way of organizing and sharing the different aspects of the data your program consumes.
4 |
5 | ## Notes
6 |
7 | * We can use the struct literal form to initialize a value from a struct type.
8 | * The dot (.) operator allows us to access individual field values.
9 | * We can create anonymous structs.
10 |
11 | ## Links
12 |
13 | http://www.goinggo.net/2013/07/understanding-type-in-go.html
14 |
15 | http://www.goinggo.net/2013/07/object-oriented-programming-in-go.html
16 |
17 | ## Code Review
18 |
19 | [Declare, create and initialize struct types](example1/example1.go) ([Go Playground](http://play.golang.org/p/-oeDmu2et8))
20 |
21 | [Anonymous struct types](example2/example2.go) ([Go Playground](http://play.golang.org/p/_xxuE1Ep6U))
22 |
23 | ## Advanced Code Review
24 |
25 | [Struct type alignments](advanced/example1/example1.go) ([Go Playground](http://play.golang.org/p/1CL1ACDipG))
26 |
27 | ## Exercises
28 |
29 | ### Exercise 1
30 |
31 | **Part A:** Declare a struct type to maintain information about a user (name, email and age). Create a value of this type, initialize with values and display each field.
32 |
33 | **Part B:** Declare and initialize an anonymous struct type with the same three fields. Display the value.
34 |
35 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/ItPe2EEy9X)) |
36 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/tnn-8hJPUd))
37 | ___
38 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
39 |
--------------------------------------------------------------------------------
/06-composition/readme.md:
--------------------------------------------------------------------------------
1 | ## Composition
2 |
3 | Composition goes beyond the mechanics of type embedding. It's a design pattern we can leverage in Go to build larger programs from smaller parts. These smaller parts come from the declaration and implementation of types that have a single focus. Programs that are architected with composition in mind have a better chance to grow and adapt to changes.
4 |
5 | ## Notes
6 |
7 | * Declare types and behavior with composition in mind.
8 | * Composition is like building software with lego blocks.
9 | * This is much more than the mechanics of type embedding.
10 |
11 | ## Links
12 |
13 | http://golang.org/doc/effective_go.html#embedding
14 |
15 | ## Code Review
16 |
17 | [Composition I](example1/example1.go) ([Go Playground](http://play.golang.org/p/W5ya6_LAU6))
18 |
19 | [Composition II](example2/example2.go) ([Go Playground](http://play.golang.org/p/xsDJhCYOBA))
20 |
21 | ## Exercises
22 |
23 | ### Exercise 1
24 |
25 | **Part A** Follow the guided comments to:
26 |
27 | **Part B** Declare a sysadmin type that implements the administrator interface.
28 |
29 | **Part C** Declare a programmer type that implements the developer interface.
30 |
31 | **Part D** Declare a company type that embeds both an administrator and a developer.
32 |
33 | **Part E** Create a sysadmin, programmers, and a company which are available for hire, and use them to complete some predefined tasks.
34 |
35 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/b8ww3jd2Xs)) |
36 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/8t5ns3cqNp))
37 | ___
38 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
39 |
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/exercises/exercise1/exercise1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/v7fEyd86i3
5 |
6 | // Write a program where two goroutines pass an integer back and forth
7 | // ten times. Display when each goroutine receives the integer. Increment
8 | // the integer with each pass. Once the integer equals ten, terminate
9 | // the program cleanly.
10 | package main
11 |
12 | import (
13 | "fmt"
14 | "sync"
15 | )
16 |
17 | // wg is used to wait for the program to finish.
18 | var wg sync.WaitGroup
19 |
20 | // main is the entry point for all Go programs.
21 | func main() {
22 | // Create an unbuffered channel.
23 | share := make(chan int)
24 |
25 | // Add a count of two, one for each goroutine.
26 | wg.Add(2)
27 |
28 | // Launch two goroutines.
29 | go goroutine("Bill", share)
30 | go goroutine("Lisa", share)
31 |
32 | // Start the sharing.
33 | share <- 1
34 |
35 | // Wait for the program to finish.
36 | wg.Wait()
37 | }
38 |
39 | // goroutine simulates sharing a value.
40 | func goroutine(name string, share chan int) {
41 | for {
42 | // Wait for the ball to be hit back to us.
43 | value, ok := <-share
44 | if !ok {
45 | // If the channel was closed, shutdown.
46 | wg.Done()
47 | fmt.Printf("Goroutine %s Down\n", name)
48 | return
49 | }
50 |
51 | // Display the value.
52 | fmt.Printf("Goroutine %s Inc %d\n", name, value)
53 |
54 | // Terminate when the value is 10.
55 | if value == 10 {
56 | close(share)
57 | wg.Done()
58 | fmt.Printf("Goroutine %s Down\n", name)
59 | return
60 | }
61 |
62 | // Share the value.
63 | share <- (value + 1)
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/05-using_pointers/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/H5HRoElN6q
5 |
6 | // Sample code to show how the standard library in general,
7 | // does not pass built-in type values with a pointer.
8 |
9 | // *******************************************************
10 |
11 | // http://golang.org/src/os/env.go
12 | //
13 | // For the caller to use this function, they must pass a copy of their uint8 type
14 | // value into the function. This is the same for the return value. A copy of the
15 | // function’s bool type value is being returned back to the caller.
16 | func isShellSpecialVar(c uint8) bool {
17 | switch c {
18 | case '*', '#', '$', '@', '!', '?', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
19 | return true
20 | }
21 | return false
22 | }
23 |
24 | // http://golang.org/src/os/env.go
25 | //
26 | // It is best to treat values of type string the same way you treat boolean
27 | // and numeric type values, as a primitive data value.
28 | func getShellName(s string) (string, int) {
29 | switch {
30 | case s[0] == '{':
31 | . . .
32 | return "", 1 // Bad syntax; just eat the brace.
33 | case isShellSpecialVar(s[0]):
34 | return s[0:1], 1
35 | }
36 | . . .
37 | return s[:i], i
38 | }
39 |
40 | // http://golang.org/src/strings/strings.go
41 | //
42 | // All of the functions in the strings package accept copies of the caller’s
43 | // string values and return copies of the string values they create.
44 | func Trim(s string, cutset string) string {
45 | if s == "" || cutset == "" {
46 | return s
47 | }
48 | return TrimFunc(s, makeCutsetFunc(cutset))
49 | }
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/exercises/exercise2/exercise2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/K9gNyTRA0s
5 |
6 | // Write a problem that uses a buffered channel to maintain a buffer
7 | // of four strings. In main, send the strings 'A', 'B', 'C' and 'D'
8 | // into the channel. Then create 20 goroutines that receive a string
9 | // from the channel, display the value and then send the string back
10 | // into the channel. Once each goroutine is done performing that task,
11 | // allow the goroutine to terminate.
12 | package main
13 |
14 | import (
15 | "fmt"
16 | "sync"
17 | )
18 |
19 | const (
20 | goroutines = 20
21 | capacity = 4
22 | )
23 |
24 | // wg is used to wait for the program to finish.
25 | var wg sync.WaitGroup
26 |
27 | // resources is a buffered channel to manage strings.
28 | var resources = make(chan string, capacity)
29 |
30 | // main is the entry point for all Go programs.
31 | func main() {
32 | // Launch goroutines to handle the work.
33 | wg.Add(goroutines)
34 | for gr := 1; gr <= goroutines; gr++ {
35 | go worker(gr)
36 | }
37 |
38 | // Add the strings.
39 | for rune := 'A'; rune < 'A'+capacity; rune++ {
40 | resources <- string(rune)
41 | }
42 |
43 | // Wait for all the work to get done.
44 | wg.Wait()
45 | }
46 |
47 | // worker is launched as a goroutine to process work from
48 | // the buffered channel.
49 | func worker(worker int) {
50 | // Receive a string from the channel.
51 | value := <-resources
52 |
53 | // Display the value.
54 | fmt.Printf("Worker: %d : %s\n", worker, value)
55 |
56 | // Place the string back.
57 | resources <- value
58 |
59 | // Tell main we are done.
60 | wg.Done()
61 | }
62 |
--------------------------------------------------------------------------------
/07-error_handling/exercises/template1/template1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/Rt3O-7ndtJ
5 |
6 | // Create two error variables, one called ErrInvalidValue and the other
7 | // called ErrAmountTooLarge. Provide the static message for each variable.
8 | // Then write a function called checkAmount that accepts a float64 type value
9 | // and returns an error value. Check the value for zero and if it is, return
10 | // the ErrInvalidValue. Check the value for greater than $1,000 and if it is,
11 | // return the ErrAmountTooLarge. Write a main function to call the checkAmount
12 | // function and check the return error value. Display a proper message to the screen.
13 | package main
14 |
15 | // Add imports.
16 |
17 | // Declare an error variable named ErrInvalidValue using the New
18 | // function from the errors package.
19 |
20 | // Declare an error variable named ErrAmountTooLarge using the New
21 | // function from the errors package.
22 |
23 | // Declare a function named checkAmount that accepts a value of
24 | // type float64 and returns an error interface value.
25 | func checkAmount( /* parameter */ ) /* return arg */ {
26 | // Is the parameter equal to zero. If so then return
27 | // the error variable.
28 |
29 | // Is the parameter greater than 1000. If so then return
30 | // the other error variable.
31 |
32 | // Return nil for the error value.
33 | }
34 |
35 | // main is the entry point for the application.
36 | func main() {
37 | // Call the checkAmount function and check the error. Then
38 | // use a switch/case to compare the error with each variable.
39 | // Add a default case. Return if there is an error.
40 |
41 | // Display everything is good.
42 | }
43 |
--------------------------------------------------------------------------------
/03-methods_interfaces_embedding/01-methods/readme.md:
--------------------------------------------------------------------------------
1 | ## Methods - Methods, Interfaces and Embedding
2 |
3 | Methods are functions that are declared with a receiver which binds the method to a type. Then the method and can be used to operate on values or pointers of that type.
4 |
5 | ## Notes
6 |
7 | * Methods are functions that contain a receiver value.
8 | * Receivers bind a method to a type and can be value or pointers.
9 | * Methods are called against values and pointers, not packages.
10 | * Go support function and method variables.
11 |
12 | ## Links
13 |
14 | https://golang.org/doc/effective_go.html#methods
15 |
16 | http://www.goinggo.net/2014/05/methods-interfaces-and-embedded-types.html
17 |
18 | ## Code Review
19 |
20 | [Declare and receiver behavior](example1/example1.go) ([Go Playground](https://play.golang.org/p/AYsB78Dlxb))
21 |
22 | [Named typed methods](example2/example2.go) ([Go Playground](https://play.golang.org/p/zHePe-yTUw))
23 |
24 | ## Advanced Code Review
25 |
26 | [Function/Method variables](advanced/example1/example1.go) ([Go Playground](http://play.golang.org/p/MNI1jR8Ets))
27 |
28 | ## Exercises
29 |
30 | ### Exercise 1
31 |
32 | Declare a struct that represents a baseball player. Include name, atBats and hits. Declare a method that calculates a players batting average. The formula is Hits / AtBats. Declare a slice of this type and initialize the slice with several players. Iterate over the slice displaying the players name and batting average.
33 |
34 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/Rj0QfwVPhX)) |
35 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/C8Z_MiYKbc))
36 | ___
37 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
--------------------------------------------------------------------------------
/13-http/api/views/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Users Example
5 |
6 |
14 |
33 |
34 |
35 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "html/template"
6 | "io/ioutil"
7 | "net/http"
8 | "os"
9 | "strings"
10 |
11 | "github.com/theplant/blackfriday"
12 | "gopkg.in/unrolled/render.v1"
13 | )
14 |
15 | var Render = render.New(render.Options{
16 | Layout: "layout",
17 | IsDevelopment: true,
18 | })
19 |
20 | func main() {
21 | port := os.Getenv("PORT")
22 | if port == "" {
23 | port = "8080"
24 | }
25 |
26 | fs := http.FileServer(http.Dir("."))
27 | handler := func(rw http.ResponseWriter, r *http.Request) {
28 | // Render the index as the main readme
29 | if r.URL.Path == "/" {
30 | if err := renderMarkdown(rw, "README.md"); err != nil {
31 | return
32 | }
33 | // Render markdown files
34 | } else if strings.HasSuffix(r.URL.Path, ".md") {
35 | if err := renderMarkdown(rw, r.URL.Path[1:]); err != nil {
36 | return
37 | }
38 | } else if strings.HasSuffix(r.URL.Path, ".go") {
39 | if err := renderCode(rw, r.URL.Path[1:]); err != nil {
40 | return
41 | }
42 | } else {
43 | fs.ServeHTTP(rw, r)
44 | }
45 |
46 | }
47 |
48 | fmt.Println("Listening on port", port)
49 | http.ListenAndServe(":"+port, http.HandlerFunc(handler))
50 | }
51 |
52 | func renderMarkdown(rw http.ResponseWriter, name string) error {
53 | data, err := ioutil.ReadFile(name)
54 | if err != nil {
55 | http.Error(rw, "Unable to read file", 500)
56 | return err
57 | }
58 |
59 | output := blackfriday.MarkdownCommon(data)
60 | Render.HTML(rw, 200, "slide", template.HTML(output))
61 | return nil
62 | }
63 |
64 | func renderCode(rw http.ResponseWriter, name string) error {
65 | data, err := ioutil.ReadFile(name)
66 | if err != nil {
67 | http.Error(rw, "Unable to read file", 500)
68 | return err
69 | }
70 |
71 | Render.HTML(rw, 200, "code", string(data))
72 | return nil
73 | }
74 |
--------------------------------------------------------------------------------
/01-language_syntax/06-functions/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/wPVvgwPlHw
5 |
6 | // Sample program to show how we can use the blank IDentifier to ignore return values.
7 | package main
8 |
9 | import (
10 | "encoding/json"
11 | "errors"
12 | "fmt"
13 | )
14 |
15 | type (
16 | // user is a struct type that declares user information.
17 | user struct {
18 | ID int
19 | Name string
20 | }
21 |
22 | // updateStats provIDes update stats.
23 | updateStats struct {
24 | Modified int
25 | Duration float64
26 | Success bool
27 | Message string
28 | }
29 | )
30 |
31 | // main is the entry point for the application.
32 | func main() {
33 | // Declare and initialize a value of type user.
34 | u := user{
35 | ID: 1432,
36 | Name: "Betty",
37 | }
38 |
39 | // Update the user Name. Don't care about the update stats.
40 | if _, err := updateUser(&u); err != nil {
41 | fmt.Println(err)
42 | return
43 | }
44 |
45 | // Display the update was Successful.
46 | fmt.Println("Updated user record for ID", u.ID)
47 | }
48 |
49 | // updateUser updates the specified user document.
50 | func updateUser(u *user) (*updateStats, error) {
51 | // response simulates a JSON response.
52 | response := `{"Modified":1, "Duration":0.005, "Success" : true, "Message": "updated"}`
53 |
54 | // Unmarshal the json document into a value of
55 | // the userStats struct type.
56 | var us updateStats
57 | if err := json.Unmarshal([]byte(response), &us); err != nil {
58 | return nil, err
59 | }
60 |
61 | // Check the update status to verify the update
62 | // was Successful.
63 | if us.Success != true {
64 | return nil, errors.New(us.Message)
65 | }
66 |
67 | return &us, nil
68 | }
69 |
--------------------------------------------------------------------------------
/11-standard_library/02-encoding/readme.md:
--------------------------------------------------------------------------------
1 | ## Encoding - Standard Library
2 |
3 | Encoding is the process or marshaling or unmarshaling data into different forms. Taking JSON string documents and convert them to values of our user defined types is a very common practice in many go programs today. Go's support for encoding is amazing and improves and gets faster with every release.
4 |
5 | ## Notes
6 |
7 | * Support for Decoding and Encoding JSON and XML are provided by the standard libary.
8 | * This package gets better and better with every release.
9 |
10 | ## Links
11 |
12 | http://www.goinggo.net/2014/01/decode-json-documents-in-go.html
13 |
14 | ## Code Review
15 |
16 | [Unmarshal JSON documents](example1/example1.go) ([Go Playground](http://play.golang.org/p/ocxFH62yaw))
17 |
18 | [Unmarshal JSON files](example2/example2.go) ([Go Playground](http://play.golang.org/p/IWfOJbmMdL))
19 |
20 | [Marshal a user defined type](example3/example3.go) ([Go Playground](http://play.golang.org/p/rLDpqYbnGR))
21 |
22 | [Custom Marshaler and Unmarshler](example4/example4.go) ([Go Playground](http://play.golang.org/p/TOYrZJoLei))
23 |
24 | ## Exercises
25 |
26 | ### Exercise 1
27 |
28 | **Part A** Create a file with an array of JSON documents that contain a user name and email address. Declare a struct type that maps to the JSON document. Using the json package, read the file and create a slice of this struct type. Display the slice.
29 |
30 | **Part B** Marshal the slice into pretty print strings and display each element.
31 |
32 | [Template](exercises/template1/template1.go) ([Go Playground](http://play.golang.org/p/OkIHsVwMQ7)) |
33 | [Answer](exercises/exercise1/exercise1.go) ([Go Playground](http://play.golang.org/p/Huf8jEDUJO))
34 | ___
35 | All material is licensed under the [GNU Free Documentation License](https://github.com/gobridge/gotraining/blob/master/LICENSE).
36 |
--------------------------------------------------------------------------------
/01-language_syntax/06-functions/advanced/example1/example1.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/eg14ClW4_y
5 |
6 | // Sample program to show how to trap panics that can occur from the Go runtime.
7 | package main
8 |
9 | import (
10 | "fmt"
11 | "runtime"
12 | )
13 |
14 | // main is the entry point for the application.
15 | func main() {
16 | // Call the testPanic function to run the test.
17 | if err := testPanic(); err != nil {
18 | fmt.Println("Error:", err)
19 | }
20 | }
21 |
22 | // catchPanic catches panics and processes the error.
23 | func catchPanic(err *error) {
24 | // Check if a panic occurred.
25 | if r := recover(); r != nil {
26 | fmt.Println("PANIC Deferred")
27 |
28 | // Capture the stack trace
29 | buf := make([]byte, 10000)
30 | runtime.Stack(buf, false)
31 | fmt.Println("Stack Trace:", string(buf))
32 |
33 | // If the caller wants the error back provide it.
34 | if err != nil {
35 | *err = fmt.Errorf("%v", r)
36 | }
37 | }
38 | }
39 |
40 | // mimicError is a function that simulates an error for
41 | // testing the code.
42 | func mimicError(key string) error {
43 | return fmt.Errorf("Mimic Error : %s", key)
44 | }
45 |
46 | // testPanic simulates a function that encounters a panic to
47 | // test our catchPanic function.
48 | func testPanic() (err error) {
49 | // Schedule the catchPanic function to be called when
50 | // the testPanic function returns.
51 | defer catchPanic(&err)
52 |
53 | fmt.Println("Start Test")
54 |
55 | // Mimic a traditional error from a function.
56 | err = mimicError("1")
57 |
58 | // Trying to dereference a nil pointer will cause the
59 | // runtime to panic.
60 | var p *int
61 | *p = 10
62 |
63 | fmt.Println("End Test")
64 | return err
65 | }
66 |
--------------------------------------------------------------------------------
/08-concurrency_channels/02-race_conditions/example4/example4.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // https://play.golang.org/p/nr8BM7lvNA
5 |
6 | // go build -race
7 |
8 | // Sample program to show how to use a mutex to define critical
9 | // sections of code that need synchronous access.
10 | package main
11 |
12 | import (
13 | "fmt"
14 | "runtime"
15 | "sync"
16 | )
17 |
18 | // counter is a variable incremented by all goroutines.
19 | var counter int
20 |
21 | // wg is used to wait for the program to finish.
22 | var wg sync.WaitGroup
23 |
24 | // mutex is used to define a critical section of code.
25 | var mutex sync.Mutex
26 |
27 | // main is the entry point for all Go programs.
28 | func main() {
29 | // Add a count of two, one for each goroutine.
30 | wg.Add(2)
31 |
32 | // Create two goroutines.
33 | go incCounter(1)
34 | go incCounter(2)
35 |
36 | // Wait for the goroutines to finish.
37 | wg.Wait()
38 | fmt.Printf("Final Counter: %d\n", counter)
39 | }
40 |
41 | // incCounter increments the package level Counter variable
42 | // using the Mutex to synchronize and provide safe access.
43 | func incCounter(id int) {
44 | for count := 0; count < 2; count++ {
45 | // Only allow one goroutine through this
46 | // critical section at a time.
47 | mutex.Lock()
48 | {
49 | // Capture the value of counter.
50 | value := counter
51 |
52 | // Yield the thread and be placed back in queue.
53 | runtime.Gosched()
54 |
55 | // Increment our local value of counter.
56 | value++
57 |
58 | // Store the value back into counter.
59 | counter = value
60 | }
61 | mutex.Unlock()
62 | // Release the lock and allow any
63 | // waiting goroutine through.
64 | }
65 |
66 | // Tell main we are done.
67 | wg.Done()
68 | }
69 |
--------------------------------------------------------------------------------
/08-concurrency_channels/03-channels/example2/example2.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // http://play.golang.org/p/AzJuQsPG3a
5 |
6 | // Sample program to show how to use an unbuffered channel to
7 | // simulate a relay race between four goroutines.
8 | package main
9 |
10 | import (
11 | "fmt"
12 | "sync"
13 | "time"
14 | )
15 |
16 | // wg is used to wait for the program to finish.
17 | var wg sync.WaitGroup
18 |
19 | // main is the entry point for all Go programs.
20 | func main() {
21 | // Create an unbuffered channel.
22 | track := make(chan int)
23 |
24 | // Add a count of one for the last runner.
25 | wg.Add(1)
26 |
27 | // First runner to his mark.
28 | go Runner(track)
29 |
30 | // Start the race.
31 | track <- 1
32 |
33 | // Wait for the race to finish.
34 | wg.Wait()
35 | }
36 |
37 | // Runner simulates a person running in the relay race.
38 | func Runner(track chan int) {
39 | // The number of exchanges of the baton.
40 | const maxExchanges = 4
41 |
42 | var exchange int
43 |
44 | // Wait to receive the baton.
45 | baton := <-track
46 |
47 | // Start running around the track.
48 | fmt.Printf("Runner %d Running With Baton\n", baton)
49 |
50 | // New runner to the line.
51 | if baton < maxExchanges {
52 | exchange = baton + 1
53 | fmt.Printf("Runner %d To The Line\n", exchange)
54 | go Runner(track)
55 | }
56 |
57 | // Running around the track.
58 | time.Sleep(100 * time.Millisecond)
59 |
60 | // Is the race over.
61 | if baton == maxExchanges {
62 | fmt.Printf("Runner %d Finished, Race Over\n", baton)
63 | wg.Done()
64 | return
65 | }
66 |
67 | // Exchange the baton for the next runner.
68 | fmt.Printf("Runner %d Exchange With Runner %d\n",
69 | baton,
70 | exchange)
71 |
72 | track <- exchange
73 | }
74 |
--------------------------------------------------------------------------------
/10-testing/01-testing/example4/handlers/handlers_test.go:
--------------------------------------------------------------------------------
1 | // All material is licensed under the GNU Free Documentation License
2 | // https://github.com/gobridge/gotraining/blob/master/LICENSE
3 |
4 | // Sample test to show how to test the execution of an internal endpoint.
5 | package handlers_test
6 |
7 | import (
8 | "encoding/json"
9 | "net/http"
10 | "net/http/httptest"
11 | "testing"
12 |
13 | "github.com/gobridge/gotraining/10-testing/01-testing/example4/handlers"
14 | )
15 |
16 | const succeed = "\u2713"
17 | const failed = "\u2717"
18 |
19 | func init() {
20 | handlers.Routes()
21 | }
22 |
23 | // TestSendJSON testing the sendjson internal endpoint.
24 | func TestSendJSON(t *testing.T) {
25 | t.Log("Given the need to test the SendJSON endpoint.")
26 | {
27 | r, _ := http.NewRequest("GET", "/sendjson", nil)
28 | w := httptest.NewRecorder()
29 | http.DefaultServeMux.ServeHTTP(w, r)
30 |
31 | if w.Code != 200 {
32 | t.Fatalf("\tShould receive a status code of \"200\" for the response. Received[%d] %s", w.Code, failed)
33 | }
34 | t.Log("\tShould receive a status code of \"200\" for the response.", succeed)
35 |
36 | u := struct {
37 | Name string
38 | Email string
39 | }{}
40 | if err := json.NewDecoder(w.Body).Decode(&u); err != nil {
41 | t.Fatal("\tShould be able to decode the response.", failed)
42 | }
43 | t.Log("\tShould be able to decode the response.", succeed)
44 |
45 | if u.Name == "Bill" {
46 | t.Log("\tShould have \"Bill\" for Name in the response.", succeed)
47 | } else {
48 | t.Error("\tShould have \"Bill\" for Name in the response.", failed, u.Name)
49 | }
50 |
51 | if u.Email == "bill@ardanstudios.com" {
52 | t.Log("\tShould have \"bill@ardanstudios.com\" for Email in the response.", succeed)
53 | } else {
54 | t.Error("\tShould have \"bill@ardanstudios.com\" for Email in the response.", failed, u.Email)
55 | }
56 | }
57 | }
58 |
--------------------------------------------------------------------------------