├── .gitignore
├── README.md
├── basic-types
├── Basic Types.key
├── Basic Types.pdf
├── Basic Types.pptx
├── README.md
├── bool
│ └── main.go
├── byte
│ └── main.go
├── complex
│ └── main.go
├── exercise
│ └── main.go
├── float
│ └── main.go
├── int
│ └── main.go
├── rune
│ └── main.go
├── string
│ ├── interpreted.go
│ ├── main.go
│ ├── raw.go
│ └── underlying-structure.go
├── uint
│ └── main.go
└── uintptr
│ └── main.go
├── constants
├── Constants.key
├── Constants.pdf
├── Constants.pptx
├── README.md
├── blank-identifier
│ ├── filename.txt
│ └── main.go
├── c-vs-go
│ ├── exec
│ ├── main.c
│ └── main.go
├── default-kind-types
│ └── main.go
├── high-precision
│ └── main.go
├── implicit-type-conversion
│ ├── by-syntax.go
│ └── by-type.go
├── iota
│ └── main.go
├── kind-promotion
│ └── main.go
├── overflow
│ └── main.go
├── scope
│ ├── main.go
│ ├── p1
│ │ └── p1.go
│ └── p2
│ │ └── p2.go
├── strings
│ └── main.go
└── types
│ └── main.go
├── custom-import-path
├── Custom import path.key
├── Custom import path.pdf
├── Custom import path.pptx
├── README.md
├── custom-path
│ ├── main.go
│ └── server.go
└── import-path-checking
│ ├── README.md
│ └── main.go
├── custom-package-manager
├── Custom package manger.key
├── README.md
└── pkg-manager
│ ├── downloader.go
│ ├── go-pkg.json
│ ├── main.go
│ └── manager.go
├── go-commands.md
├── go-environment-variables
└── README.md
├── go-learning-resources
├── Go Resources.key
├── Go Resources.pdf
├── Go Resources.pptx
└── README.md
├── go-module-proxy
├── Go module proxy.key
└── README.md
├── go-modules
├── @latest
│ └── main.go
├── Go modules.key
├── README.md
├── basic-http
│ └── main.go
├── download
│ └── main.go
├── go-mod-tidy
│ └── main.go
├── go111module
│ └── main.go
├── incompatible-pkg-versions
│ └── main.go
├── migration-from-dep
│ └── main.go
├── outside-gopath
│ └── main.go
└── vendor-directory
│ └── main.go
├── go-program-anatomy
├── Go program anatomy.key
├── Go program anatomy.pdf
├── Go program anatomy.pptx
├── README.md
├── go-build
│ ├── bip_darwin_386.go
│ ├── bip_darwin_amd64.go
│ ├── bip_linux_386.go
│ ├── bip_linux_amd64.go
│ ├── good-bye-darwin-386.go
│ ├── good-bye-darwin-amd64.go
│ ├── good-bye-linux-386.go
│ ├── good-bye-linux-amd64.go
│ ├── greet_darwin.go
│ ├── greet_linux.go
│ ├── main.go
│ ├── welcome-linux.go
│ └── welcome-osx.go
├── program-flow
│ ├── main.go
│ ├── pkg1
│ │ └── pkg1.go
│ ├── pkg2
│ │ └── pkg2.go
│ └── pkg3
│ │ └── pkg3.go
└── runtime-vs-buildtime
│ └── main.go
├── go-workspace.md
├── gophertuts.svg
├── internal-directory
├── Internal directory.key
└── README.md
├── number-systems
├── Number systems.key
├── Number systems.pdf
├── Number systems.pptx
└── README.md
├── package-management
├── Package management.key
├── README.md
├── basic-http
│ ├── Gopkg.lock
│ ├── Gopkg.toml
│ ├── app
│ │ └── app.go
│ ├── config
│ │ ├── config.go
│ │ └── config.yaml
│ ├── controllers
│ │ ├── index.go
│ │ ├── people.go
│ │ └── routes.go
│ ├── logging
│ │ └── logger.go
│ └── main.go
├── cmd-directory
│ └── main.go
├── custom-library
│ ├── internal
│ │ └── pkg.go
│ └── main.go
├── dep
│ └── main.go
├── glide
│ └── main.go
├── go-mod
│ └── main.go
├── internal-directory
│ └── main.go
├── package-archives
│ └── main.go
├── private-packages
│ └── main.go
├── semver
│ └── main.go
└── vendor-directory
│ └── main.go
├── packages
├── Packages.key
├── Packages.pdf
├── Packages.pptx
├── README.md
├── cross-reference
│ ├── main.go
│ ├── p1
│ │ └── p1.go
│ └── p2
│ │ └── p2.go
├── exported-vs-unexported
│ ├── main.go
│ └── pkg
│ │ └── pkg.go
├── go-get
│ ├── README.md
│ ├── go.mod
│ ├── go.sum
│ └── main.go
├── locals-vs-globals
│ ├── main.go
│ └── square.go
├── multiple-packages
│ ├── main.go
│ ├── pkgA.go
│ └── pkgB.go
├── package-naming
│ ├── anotherWeirdPkg
│ │ └── another-weird.go
│ ├── collision
│ │ └── collision.go
│ ├── main.go
│ ├── redundant
│ │ └── redundant.go
│ ├── right
│ │ └── wrong.go
│ └── weird_long_package_name_with_underscores
│ │ └── weird.go
├── package-organization
│ ├── controllers
│ │ ├── c1.go
│ │ ├── c1_test.go
│ │ ├── c2.go
│ │ ├── c2_test.go
│ │ ├── controllers.go
│ │ └── controllers_test.go
│ └── main.go
├── package-types
│ ├── main.go
│ └── services
│ │ └── s1.go
└── test-packages
│ ├── pkg1
│ ├── pkg1.go
│ └── pkg1_test.go
│ └── pkg2
│ ├── pkg2.go
│ └── pkg2_test.go
└── vendor-directory
├── README.md
├── Vendor directory.key
├── Vendor directory.pdf
├── Vendor directory.pptx
├── main.go
├── pkg1
└── pkg1.go
├── pkg2
└── pkg2.go
├── pkg3
└── pkg3.go
└── vendor
└── github.com
├── gophertuts
└── go-basics
│ └── vendor-directory
│ └── pkg3
│ └── pkg3.go
└── julienschmidt
└── httprouter
└── router.go
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/
3 | **/vendor
4 | !vendor-directory/vendor/
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # go-basics
2 |
3 | ## Go language basics
4 |
5 | This section includes exercises and small projects which illustrate the basics of Go programming language. Things such as: types, data structures, functions, pointers, packages and others.
6 |
7 | ## Section overview
8 |
9 | - [Go Learning Resources](https://github.com/gophertuts/go-basics/blob/master/go-learning-resources)
10 | - [Go Program Anatomy](https://github.com/gophertuts/go-basics/blob/master/go-program-anatomy)
11 | - [Number Systems](https://github.com/gophertuts/go-basics/blob/master/number-systems)
12 | - [Basic Types](https://github.com/gophertuts/go-basics/blob/master/basic-types)
13 | - [Constants](https://github.com/gophertuts/go-basics/blob/master/constants)
14 | - [Packages](https://github.com/gophertuts/go-basics/blob/master/packages)
15 | - [Vendor directory](https://github.com/gophertuts/go-basics/blob/master/vendor-directory)
16 | - [Custom import paths](https://github.com/gophertuts/go-basics/blob/master/custom-import-paths)
17 | - [Custom package manager](https://github.com/gophertuts/go-basics/blob/master/custom-package-manager)
18 | - [Package Management](https://github.com/gophertuts/go-basics/blob/master/package-management)
19 | - [Go modules](https://github.com/gophertuts/go-basics/blob/master/go-modules)
20 | - [Go module proxy](https://github.com/gophertuts/go-basics/blob/master/go-module-proxy)
21 | - [Internal directory](https://github.com/gophertuts/go-basics/blob/master/internal-directory)
22 |
23 | ### Installation
24 |
25 | Before trying any of these examples make sure to have the `Go` binary installed on your platform.
26 |
27 | OSX:
28 |
29 | ```bash
30 | # Install Homebrew
31 |
32 | /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
33 | ```
34 |
35 | ```bash
36 | # Install Go
37 |
38 | brew install go
39 | ```
40 |
41 | Linux:
42 |
43 | ```bash
44 | # Move into $HOME directory
45 | cd ~
46 |
47 | # Download the binary for your distribution
48 | curl -O https://dl.google.com/go/go1.12.linux-amd64.tar.gz
49 |
50 | # Verify that the downloaded binary is not corrupted. Check if the hash matches the one from downloads page
51 | sha256sum go1.12.linux-amd64.tar.gz
52 |
53 | # Extract the binary
54 | tar xvf go1.12.linux-amd64.tar.gz
55 |
56 | # Make root user the owner of Go workspace
57 | sudo chown -R root:root ./go
58 |
59 | # Move go directory to a standard location
60 | sudo mv go /usr/local
61 | ```
62 |
63 | For more details regarding `Go` installation check out
64 |
65 | [Golang Installation](https://golang.org/doc/install)
66 |
67 | For downloading `Go` binary for your platform checkout
68 |
69 | [Golang Downloads](https://golang.org/dl/)
70 |
71 | To check if you installed `Go` successfully type:
72 |
73 | ```bash
74 | # Displays installed Go version
75 | go version
76 |
77 | # Displays all environment variables defined by Go
78 | go env
79 | ```
80 |
81 | Docker:
82 |
83 | ```bash
84 | docker run -it golang:1.11
85 | ```
86 |
87 | ### Set $GOPATH variable
88 | ```bash
89 | sudo nano ~/.profile
90 |
91 | # Linux
92 | export GOPATH=/usr/local/go
93 | export GOBIN=$GOPATH/bin
94 | export PATH=$PATH:/$GOBIN
95 |
96 | # OSX
97 | export GOPATH=$HOME/go
98 | export GOBIN=$GOPATH/bin
99 | export PATH=$PATH:/$GOBIN
100 |
101 | # Save File
102 |
103 | # Restart shell configuration
104 | source ~/.profile
105 | ```
106 |
107 | ### Other Go tools
108 |
109 | You can also install other `Go` tools which will help you have a more productive development process
110 |
111 | - [Go Tools](https://github.com/golang/tools)
112 | - [Go Lint](https://github.com/golang/lint)
113 | - [Go Imports](https://godoc.org/golang.org/x/tools/cmd/goimports)
114 |
115 | #### Go Tools
116 |
117 | ```bash
118 | go get -u golang.org/x/tools/...
119 | ```
120 |
121 | #### Go Lint
122 |
123 | ```bash
124 | go get -u golang.org/x/lint/golint
125 | ```
126 |
127 | #### Go Imports
128 |
129 | ```bash
130 | go get -u golang.org/x/tools/cmd/goimports
131 | ```
132 |
133 | #### Daily routine things
134 |
135 | - Format your entire code recursively using
136 | `go fmt ./...`
137 |
138 | - Lint your entire code recursively using
139 | `golint ./...`
140 |
141 | ### For more info about Go check out
142 |
143 | [Go Doc](https://golang.org/pkg)
144 |
145 | [Go Packages](https://godoc.org/)
146 |
147 | [Go Playground](https://play.golang.org/)
148 |
149 | [Effective Go](https://golang.org/doc/effective_go.html)
150 |
151 | [A Tour of Go](https://tour.golang.org/)
152 |
153 |
154 | ### For more info about Go commands & WORKSPACE check out
155 |
156 | [Go commands explained](https://github.com/gophertuts/go-basics/blob/master/go-commands.md)
157 |
158 | [Go WORKSPACE explained](https://github.com/gophertuts/go-basics/blob/master/go-workspace.md)
159 |
160 | ## FEEDBACK ⚗
161 |
162 | [GopherTuts TypeForm](https://feedback.gophertuts.com)
163 |
164 | ## COMMUNITY 🙌
165 |
166 | [GopherTuts Discord](https://discord.gg/4sgecdh)
167 |
168 | ---
169 |
170 | Happy hacking gophers 🚀🚀🚀
171 |
172 |
--------------------------------------------------------------------------------
/basic-types/Basic Types.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/basic-types/Basic Types.key
--------------------------------------------------------------------------------
/basic-types/Basic Types.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/basic-types/Basic Types.pdf
--------------------------------------------------------------------------------
/basic-types/Basic Types.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/basic-types/Basic Types.pptx
--------------------------------------------------------------------------------
/basic-types/README.md:
--------------------------------------------------------------------------------
1 | # Basic Types in Go
2 |
3 | ## Overall types discussed in this tutorial:
4 |
5 | - bool
6 | - int
7 | - int8
8 | - int16
9 | - int32/rune
10 | - int64
11 | - int64
12 | - uint
13 | - uint8/byte
14 | - uint16
15 | - uint32
16 | - uint64
17 | - uint64
18 | - uintptr
19 | - float32
20 | - float64
21 | - complex64
22 | - complex128
23 | - string
24 |
25 | Note: `int`, `uint`, `uintptr`, `string` sizes are platform dependent
26 | In case you want to simulate x32 or x64 platform architecture
27 | follow the instructions below
28 |
29 | ## Simulate x32 / x64 bit architecture
30 |
31 | ```bash
32 | # cd into the project i.e. int examples
33 | cd $GOPATH/src/github.com/gophertuts/go-basics/basic-types/int
34 |
35 | # 32bit
36 | env GOARCH=386 go run main.go
37 |
38 | # 64bit
39 | env GOARCH=amd64 go run main.go
40 |
41 | # $GOARCH => $GOHOSTARCH will be taken
42 | go run main.go
43 |
44 | # to check you host architecture run
45 | go env | grep GOHOSTARCH
46 | ```
47 |
48 | ## Resources 💎
49 |
50 | - [String implementation](https://github.com/golang/go/blob/master/src/runtime/string.go)
51 | - [Strings - Go101](https://go101.org/article/string.html)
52 | - [Unsafe package](https://golang.org/pkg/unsafe/)
53 | - [Unsafe - Go101](https://go101.org/article/unsafe.html)
54 | - [UintPtr vs Unsafe pointer](https://utcc.utoronto.ca/~cks/space/blog/programming/GoUintptrVsUnsafePointer)
55 | - [Complex numbers](https://en.wikipedia.org/wiki/Complex_number)
56 | - [Floating point numbers](https://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html)
57 | - [IEEE standard 754](https://www.geeksforgeeks.org/ieee-standard-754-floating-point-numbers/)
58 | - [How are floating numbers stored in memory](https://stackoverflow.com/questions/7644699/how-are-floating-point-numbers-stored-in-memory)
59 | - [How to normalize a mantissa](https://stackoverflow.com/questions/28800565/how-to-normalize-a-mantissa)
60 |
61 |
62 | ## Related tutorials
63 | - [Number systems](https://github.com/gophertuts/go-basics/blob/master/number-systems)
64 |
65 | ## FEEDBACK ⚗
66 |
67 | [GopherTuts TypeForm](https://gophertuts.typeform.com/to/j2CJmC)
68 |
69 | ## COMMUNITY 🙌
70 |
71 | [GopherTuts Discord](https://discord.gg/4sgecdh)
72 |
73 | ---
74 |
75 | Back to
76 | [Go Basics](https://github.com/gophertuts/go-basics)
77 |
78 |
79 |
--------------------------------------------------------------------------------
/basic-types/bool/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | const num = 10
9 |
10 | func main() {
11 | fmt.Println(unsafe.Sizeof(true))
12 | fmt.Println(unsafe.Sizeof(false))
13 | fmt.Println(unsafe.Sizeof(1 > 10))
14 | fmt.Println(unsafe.Sizeof(!true))
15 | if num > 3 {
16 | fmt.Println(`"num" is greater than 3`)
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/basic-types/byte/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | const (
9 | b1 byte = 1
10 | b3 byte = 255 // if greater than 255: const will overflow byte
11 | )
12 |
13 | var (
14 | b2 byte = 'A'
15 | )
16 |
17 | func main() {
18 | fmt.Printf("%T\n", b1)
19 | fmt.Println(unsafe.Sizeof(b1))
20 | fmt.Println("uint value", b2, "string value", string(b2))
21 | fmt.Println(b3)
22 | // automatic conversion to 'uint8'
23 | fmt.Printf("value of: A + B = %[1]v | type: %[1]T\n", 'A'+b2)
24 | // no conversion is done, falling back to 'int32' aka 'rune'
25 | fmt.Printf("value of: A + B = %[1]v | type: %[1]T\n", 'A'+'B')
26 | }
27 |
--------------------------------------------------------------------------------
/basic-types/complex/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | var (
9 | c64 complex64 = 12
10 | c128 complex128 = 128
11 | c128_2 = 3i
12 | c128_3 = +0i
13 | c64_2 complex64 = 3 + 15
14 | )
15 |
16 | func main() {
17 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c64), c64)
18 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c128), c128)
19 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c128_2), c128_2)
20 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c128_3), c128_3)
21 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c64_2), c64_2)
22 | fmt.Println(unsafe.Sizeof(1 + 2i)) // 128b => 16B
23 | fmt.Println(11 + 25.3*4 + 4i) // real part - 112.2 | imaginary part - 4i
24 | fmt.Println(4i) // real part - 0 | imaginary part - 4i
25 | }
26 |
--------------------------------------------------------------------------------
/basic-types/exercise/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func main() {
6 | // 你 - 3B
7 | // 好 - 3B
8 | // " " - 1B
9 | s := []byte("你 好")
10 | if len(s) == 3 {
11 | fmt.Println("String has 3 Bytes")
12 | } else {
13 | fmt.Println("String has 7 Bytes")
14 | }
15 | fmt.Println(len(s))
16 | }
17 |
--------------------------------------------------------------------------------
/basic-types/float/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | var (
9 | f32 float32 = 5 // automatic conversion to float32
10 | f64 float64 = 13 // automatic conversion to float64
11 | f64_2 = 13.2 // automatic conversion to float64
12 | )
13 |
14 | func main() {
15 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(f32), f32)
16 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(f64), f64)
17 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(f64_2), f64_2)
18 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(.2), .2)
19 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(12.5), 12.5)
20 | fmt.Printf("value: %[1]v | type: %[1]T\n", 2*3.0) // conversion to float64
21 | fmt.Printf("value: %[1]v | type: %[1]T\n", 14/3) // no conversion is done
22 | }
23 |
--------------------------------------------------------------------------------
/basic-types/int/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | const (
9 | i8 int8 = -128
10 | )
11 |
12 | var (
13 | i64 int64 = 12.0 // default conversion to int64
14 | i32 = int32(i64) // explicit conversion to int32
15 | f64 = 12.5
16 | i64_2 = int64(f64) // explicit conversion to int64
17 | c = 'A' // rune = int32
18 | r rune = 'B'
19 | )
20 |
21 | func main() {
22 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(i64), i64)
23 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c), c)
24 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(r), r)
25 | fmt.Println(i8)
26 | fmt.Println(unsafe.Sizeof(10)) // 32b/64b => 4/8B
27 | }
28 |
--------------------------------------------------------------------------------
/basic-types/rune/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | var (
9 | r1 = 65
10 | r2 = 'Z'
11 | r3 rune = 128
12 | )
13 |
14 | func main() {
15 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof('A'+'B'), 'A'+'B')
16 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(r3), r3)
17 | fmt.Printf("some char range regex: [%s-%s]\n", string(r1), string(r2))
18 | fmt.Println("Your order total is of 100", string(r3))
19 | }
20 |
--------------------------------------------------------------------------------
/basic-types/string/interpreted.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | const interpreted = "This text is interpreted\n\n \tsome tabulated text\nand a special char '\u0028'"
6 |
7 | func main() {
8 | fmt.Println(interpreted)
9 | }
10 |
--------------------------------------------------------------------------------
/basic-types/string/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | var (
9 | rs = []rune{'W', 'e', 'l', 'c', 'o', 'm', 'e', '好'}
10 | bs = []byte{'W', 'e', 'l', 'c', 'o', 'm', 'e', '!'}
11 | )
12 |
13 | func main() {
14 | s := "Hello World"
15 | // a string is just a slice of bytes or a sequence of uint8(s)
16 | fmt.Printf("%T\n", s[0])
17 | // check out the underlying string structure
18 | fmt.Println(unsafe.Sizeof(s)) // 64/128b
19 |
20 | // explicit conversion to string
21 | fmt.Println(string(rs))
22 | fmt.Println(string(bs))
23 | }
24 |
--------------------------------------------------------------------------------
/basic-types/string/raw.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | const raw = `
6 |
7 |
8 |
9 |
10 |
12 |
13 | Document
14 |
15 |
16 |
17 | `
18 |
19 | func main() {
20 | fmt.Println(raw)
21 | }
22 |
--------------------------------------------------------------------------------
/basic-types/string/underlying-structure.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | // underlying string type
9 | // check out the implementation
10 | // https://github.com/golang/go/blob/master/src/runtime/string.go
11 | // https://github.com/golang/go/blob/master/src/runtime/string.go#L224
12 | type _string struct {
13 | // 4B/8B => 32/64b - depending on GOARCH
14 | elements *byte // underlying bytes
15 | // 4B/8B => 32/64b - depending on GOARCH
16 | len int // number of bytes
17 | }
18 |
19 | func main() {
20 | var b byte
21 | var pb *byte
22 | s := "Hello World"
23 | fmt.Println(unsafe.Sizeof(_string{})) // 8/16B => 64/128b
24 | fmt.Println(unsafe.Sizeof(pb)) // 4/8B => 64b
25 | fmt.Println(unsafe.Sizeof(b)) // 4/8B => 64b
26 | fmt.Println(unsafe.Sizeof(s)) // 8/16B => 128b
27 | }
28 |
--------------------------------------------------------------------------------
/basic-types/uint/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | const (
9 | uInt8 int8 = 127
10 | )
11 |
12 | var (
13 | greatestUint32 = ^uint32(0)
14 | greatestUint64 = ^uint64(0)
15 | uInt64 uint64 = 12.0 // default conversion to int64
16 | uInt32 = int32(uInt64) // explicit conversion to int32
17 | f64 = 12.5
18 | uInt64V2 = int64(f64) // explicit conversion to int64
19 | c = 'A' // rune = int32
20 | r rune = 'B'
21 | )
22 |
23 | func main() {
24 | fmt.Println(greatestUint32)
25 | fmt.Println(greatestUint64)
26 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(uInt64), uInt64)
27 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(uInt32), uInt32)
28 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(uInt64V2), uInt64V2)
29 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(c), c)
30 | fmt.Printf("size: %d | type %T\n", unsafe.Sizeof(r), r)
31 | fmt.Println(uInt8)
32 | fmt.Println(unsafe.Sizeof(10)) // 32b/64b => 4/8B
33 | }
34 |
--------------------------------------------------------------------------------
/basic-types/uintptr/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "unsafe"
6 | )
7 |
8 | func main() {
9 | i := 10
10 |
11 | ptr1 := unsafe.Pointer(&i)
12 | fmt.Println(*(*int)(ptr1))
13 |
14 | uptr1 := uintptr(i)
15 | uptr1 += 20
16 |
17 | ptr2 := unsafe.Pointer(&uptr1)
18 | fmt.Println(*(*int)(ptr2))
19 | }
20 |
--------------------------------------------------------------------------------
/constants/Constants.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/constants/Constants.key
--------------------------------------------------------------------------------
/constants/Constants.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/constants/Constants.pdf
--------------------------------------------------------------------------------
/constants/Constants.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/constants/Constants.pptx
--------------------------------------------------------------------------------
/constants/README.md:
--------------------------------------------------------------------------------
1 | # Constants in Go
2 |
3 | ## Types of const(s)
4 |
5 | - Typed
6 | - Untyped (Kind)
7 |
8 | ## Facts about constants
9 |
10 | - Cannot be reassigned or redeclared
11 | - Can only hold scalar values
12 | - Can hold large high precision numbers
13 | - Can be created from expression of other constants
14 | - Can be untyped (Kind)
15 | - Constants only **exist** during **compilation time**
16 |
17 | ## C background
18 |
19 | #### How to run the C program
20 |
21 | ```bash
22 | # cd into the project directory
23 | cd $GOPATH/src/github.com/gophertuts/go-basics/constants/c-vs-go
24 |
25 | # compile the program
26 | gcc main.c -o exec
27 |
28 | # run the program
29 | ./exec
30 | ```
31 |
32 | ## Resources 💎
33 |
34 | - [Constants](https://blog.golang.org/constants)
35 | - [Basic Kind](https://golang.org/pkg/go/types/#Basic.Kind)
36 | - [Iota](https://github.com/golang/go/wiki/Iota)
37 | - [Identifiers](https://golang.org/ref/spec#Identifiers)
38 | - [Keywords](https://golang.org/ref/spec#Keywords)
39 | - [Numeric types](https://golang.org/ref/spec#Numeric_types)
40 | - [Representability](https://golang.org/ref/spec#Representability)
41 | - [Constant expressions](https://golang.org/ref/spec#Constant_expressions)
42 | - [Introduction to Numeric Constants](https://www.ardanlabs.com/blog/2014/04/introduction-to-numeric-constants-in-go.html)
43 | - [A Tour of Go - Basics](https://tour.golang.org/basics/1)
44 |
45 | ## FEEDBACK ⚗
46 |
47 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
48 |
49 | ## COMMUNITY 🙌
50 |
51 | [GopherTuts Discord](https://discord.gg/4sgecdh)
52 |
53 | ---
54 |
55 | Back to
56 | [Go Basics](https://github.com/gophertuts/go-basics)
57 |
58 |
59 |
--------------------------------------------------------------------------------
/constants/blank-identifier/filename.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/constants/blank-identifier/filename.txt
--------------------------------------------------------------------------------
/constants/blank-identifier/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | // unused import
5 | _ "fmt"
6 | // package side effects (like init)
7 | _ "github.com/go-sql-driver/mysql"
8 | "log"
9 | "os"
10 | )
11 |
12 | // unused const identifier
13 | const (
14 | _ = 10
15 | )
16 |
17 | func main() {
18 | // unused (ignored) error value
19 | f, _ := os.Open("filename.txt")
20 | log.Print(f.Name())
21 | }
22 |
--------------------------------------------------------------------------------
/constants/c-vs-go/exec:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/constants/c-vs-go/exec
--------------------------------------------------------------------------------
/constants/c-vs-go/main.c:
--------------------------------------------------------------------------------
1 | #include
2 |
3 | int main() {
4 | unsigned int u = 1e9;
5 | long signed int i = 1;
6 | // warning: format specifies type 'int' but the argument has type 'long' [-Wformat]
7 | printf("Result: %d\n", i + u);
8 | }
9 |
--------------------------------------------------------------------------------
/constants/c-vs-go/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | const (
6 | u uint = 1e9
7 | i int = 1
8 | )
9 |
10 | func main() {
11 | // invalid operation: i + u (mismatched types int and uint)
12 | //fmt.Println("Result", i+u)
13 | fmt.Println("Result1", uint(i) + u)
14 | fmt.Println("Result2", int(u) + i)
15 | }
16 |
--------------------------------------------------------------------------------
/constants/default-kind-types/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | const (
6 | // untyped bool - bool
7 | b = false
8 |
9 | // untyped int - int
10 | i = 12
11 |
12 | // untyped int - int
13 | j = iota
14 |
15 | // untyped rune - int32
16 | c = 'N'
17 |
18 | // untyped float - float64
19 | f = 3.5
20 | e = 1e+200
21 |
22 | // untyped complex - complex128
23 | cx = 3 + 4i
24 |
25 | // untyped string - string
26 | s = "Hello World"
27 | )
28 |
29 | func main() {
30 | fmt.Printf("b: %T\n", b)
31 | fmt.Printf("i: %T\n", i)
32 | fmt.Printf("j: %T\n", j)
33 | fmt.Printf("c: %T\n", c)
34 | fmt.Printf("f: %T\n", f)
35 | fmt.Printf("e: %T\n", e)
36 | fmt.Printf("cx: %T\n", cx)
37 | fmt.Printf("s: %T\n", s)
38 | }
39 |
--------------------------------------------------------------------------------
/constants/high-precision/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | const (
8 | // constants are only available during compile time
9 | Pi = 3.14159265358979323846264338327950288419716939937510582097494459
10 | HugeMathematicallyExact = 36893488147419103230
11 | MaxUint = 18446744073709551615
12 | //MaxUint = ^uint(0)
13 | )
14 |
15 | func main() {
16 | fmt.Println(Pi) //3.141592653589793
17 | fmt.Println(3.141592653589793 / Pi) // 0.9999999999999999
18 |
19 | // constant 36893488147419103230 overflows int
20 | //fmt.Println(uint(HugeMathematicallyExact))
21 | fmt.Println(HugeMathematicallyExact / MaxUint) // 2
22 | }
23 |
--------------------------------------------------------------------------------
/constants/implicit-type-conversion/by-syntax.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | type T complex128
6 |
7 | const t T = 1
8 |
9 | func main() {
10 | fmt.Printf("Value: %+v | Type: %T\n", 10, 10)
11 | fmt.Printf("Value: %+v | Type: %T\n", ^3, ^3)
12 | fmt.Printf("Value: %+v | Type: %T\n", 10 > 2, 10 > 2)
13 | fmt.Printf("Value: %+v | Type: %T\n", 1<<7, 1<<7)
14 | fmt.Printf("Value: %+v | Type: %T\n", 'A', 'A')
15 | fmt.Printf("Value: %+v | Type: %T\n", 11.2, 11.2)
16 | fmt.Printf("Value: %+v | Type: %T\n", 1e+15, 1e+15)
17 | fmt.Printf("Value: %+v | Type: %T\n", 1e-10, 1e-10)
18 | fmt.Printf("Value: %+v | Type: %T\n", .2, .2)
19 | fmt.Printf("Value: %+v | Type: %T\n", 12i, 12i)
20 | fmt.Printf("Value: %+v | Type: %T\n", "hello", "hello")
21 | fmt.Printf("Value: %+v | Type: %T\n", 1+2.5, 1+2.5)
22 | fmt.Printf("Value: %+v | Type: %T\n", 2/3, 2/3)
23 | fmt.Printf("Value: %+v | Type: %T\n", 10/2.0, 10/2.0)
24 | fmt.Printf("Value: %+v | Type: %T\n", 24./12, 24./12)
25 | fmt.Printf("Value: %+v | Type: %T\n", 1+13.2/t*5i-'D', 1+13.2/t*5i-'D')
26 | }
27 |
--------------------------------------------------------------------------------
/constants/implicit-type-conversion/by-type.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var (
6 | i int = 13.0
7 | f float64 = 5
8 | c complex128 = 12.3 + 5
9 | )
10 |
11 | func main() {
12 | fmt.Printf("Value: %+v | Type: %T\n", i, i)
13 | fmt.Printf("Value: %+v | Type: %T\n", f, f)
14 | fmt.Printf("Value: %+v | Type: %T\n", c, c)
15 | }
16 |
--------------------------------------------------------------------------------
/constants/iota/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | // week days
6 | const (
7 | Sunday = iota + 1
8 | Monday
9 | Tuesday
10 | Wednesday
11 | Thursday
12 | Friday
13 | Saturday
14 | )
15 |
16 | // byte multiples
17 | const (
18 | // first value is ignored (we do not want 0)
19 | _ = iota
20 | KB = 1 << (iota * 10)
21 | MB
22 | GB
23 | TB
24 | PB
25 | )
26 |
27 | func main() {
28 | fmt.Println("Week days:")
29 | fmt.Println(Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday)
30 |
31 | fmt.Println("Byte multiples:")
32 | fmt.Println(KB, MB, GB)
33 | }
34 |
--------------------------------------------------------------------------------
/constants/kind-promotion/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | )
6 |
7 | type T complex128
8 |
9 | const (
10 | t T = 1
11 | // keep the order in mind, the last from this list has the top priority in the end result type
12 | // integer, rune, floating-point, complex, string, custom type
13 | n = 2 + t*'c'*2.0 + 35i
14 | shift = 'c' << 5
15 | )
16 |
17 | func main() {
18 | fmt.Printf("%T\n", n)
19 | fmt.Printf("%T", shift)
20 | }
21 |
--------------------------------------------------------------------------------
/constants/overflow/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "math"
6 | )
7 |
8 | const Huge = 1.2676506002282294e+30
9 |
10 | func main() {
11 | // int32
12 | fmt.Println(^int32(math.Pow(2, 31))) // 2147483647
13 | fmt.Println(int32(math.Pow(2, 31))) // -2147483648
14 |
15 | // int64
16 | fmt.Println(^int64(math.Pow(2, 63))) // -9223372036854775808
17 | fmt.Println(int64(math.Pow(2, 63))) // 9223372036854775807
18 |
19 | // constants/overflow/main.go:11:13: constant 1267650600228229400000000000000 overflows int
20 | fmt.Println(int(Huge))
21 | }
22 |
--------------------------------------------------------------------------------
/constants/scope/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "github.com/gophertuts/go-basics/constants/scope/p1"
6 | )
7 |
8 | const (
9 | Exported = 10
10 | unExported = "Hello"
11 | )
12 |
13 | func main() {
14 | const (
15 | private = 10
16 | Private = "Hello"
17 | )
18 |
19 | fmt.Println("main: p1: Exported: ", p1.Exported)
20 | fmt.Println("main: Exported: ", Exported)
21 | fmt.Println("main: unExported: ", unExported)
22 | fmt.Println("main: Private: ", Private)
23 | fmt.Println("main: private: ", private)
24 | }
25 |
--------------------------------------------------------------------------------
/constants/scope/p1/p1.go:
--------------------------------------------------------------------------------
1 | package p1
2 |
3 | import (
4 | "fmt"
5 | "github.com/gophertuts/go-basics/constants/scope/p2"
6 | )
7 |
8 | const (
9 | Exported = "exported"
10 | unExported = 10
11 | )
12 |
13 | func init() {
14 | fmt.Println("p1: unExported:", unExported)
15 | fmt.Println("p1: p2: Exported:", p2.Exported)
16 | }
17 |
--------------------------------------------------------------------------------
/constants/scope/p2/p2.go:
--------------------------------------------------------------------------------
1 | package p2
2 |
3 | const Exported = 10
4 |
--------------------------------------------------------------------------------
/constants/strings/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | const s = "Hello"
6 |
7 | var bs = []rune{'H', 'e', 'l', 'l', 'o'}
8 |
9 | func main() {
10 | // cannot assign to s[0]
11 | // s[0] = 'M'
12 | fmt.Println(s)
13 |
14 | bs[0] = 'M'
15 | fmt.Println(string(bs))
16 | }
17 |
--------------------------------------------------------------------------------
/constants/types/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | const (
6 | // typed
7 | b bool = true
8 | i int = -64 - 32
9 | i8 int8 = -8
10 | i16 int16 = -16
11 | i32 int32 = -32
12 | r rune = 'c' // alias of in32
13 | i64 int64 = -64
14 | u uint = 1e2
15 | u8 uint8 = 8
16 | bb byte = 20 // alias of uint8
17 | u16 uint16 = 16
18 | u32 uint32 = 32
19 | u64 uint64 = 64
20 | uptr uintptr = '\u0001'
21 | f32 float32 = 3.2
22 | f64 float64 = 6.4
23 | c64 complex64 = 6 + 4i
24 | c128 complex128 = 12 + 8i
25 | str string = "Hello"
26 |
27 | // untyped
28 | untypedB = false
29 | untypedInt = 10
30 | untypedIntIota = iota // alias of untyped int
31 | untypedRune = '汉'
32 | untypedFloat = 2.0
33 | untypedComplex = 2 + 0i
34 | untypedString = "World"
35 |
36 | // const expressions
37 | exp1 = 4.5 + 1 + 2i
38 | exp2 = 12 + 3.5
39 | exp3 = 'H' + 'e' + 'l' + 'l' + 'o' + ' ' + 'W' + 'o' + 'r' + 'l' + 'd'
40 | exp4 = str + " " + untypedString
41 | )
42 |
43 | func main() {
44 | fmt.Printf("exp1: Value: %v Type: %T\n", exp1, exp1)
45 | fmt.Printf("exp2: Value: %v Type: %T\n", exp2, exp2)
46 | fmt.Printf("exp3: Value: %v Type: %T\n", exp3, exp3)
47 | fmt.Printf("exp4: Value: %v Type: %T\n", exp4, exp4)
48 | }
49 |
--------------------------------------------------------------------------------
/custom-import-path/Custom import path.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/custom-import-path/Custom import path.key
--------------------------------------------------------------------------------
/custom-import-path/Custom import path.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/custom-import-path/Custom import path.pdf
--------------------------------------------------------------------------------
/custom-import-path/Custom import path.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/custom-import-path/Custom import path.pptx
--------------------------------------------------------------------------------
/custom-import-path/README.md:
--------------------------------------------------------------------------------
1 | # Custom **import** path in Go
2 |
3 | ## Overview
4 |
5 | The purpose of this tutorial is to teach you what are custom import
6 | paths in Go and how can you make use of this feature to your advantage.
7 |
8 | In this tutorial you will learn how to set up a custom import path
9 | static Go server, which tells us the client which cloud provider
10 | to use for our import and we'll have a small program
11 | which uses that package.
12 |
13 | The main topics we're gonna cover are:
14 |
15 | - `Custom import paths`
16 | - `Import path checking`
17 |
18 | ## Medium version 📖
19 |
20 | [Custom import paths in Go](https://medium.com/@gophertuts/packages-in-go-df5438123548)
21 |
22 | ### How to run:
23 |
24 | 1. Custom `go get` **import** path
25 |
26 | ```bash
27 | # cd into the example
28 | cd $GOPATH/src/github.com/gophertuts/go-basics/custom-import-path/custom-path
29 |
30 | # fetch the package from custom URL
31 | go get -insecure -u 0.0.0.0/user/pkg
32 |
33 | # spin an HTTP static server
34 | go run server.go
35 | ```
36 |
37 | #### Run GitLab Docker server:
38 |
39 | ***Disclaimer***: GitLab says it's not guaranteed to work on Windows,
40 | so if you happen to use Windows. You can try this out, but not
41 | sure it's going to reproduce or work properly.
42 |
43 | You can though try it on Linux, i.e. Ubuntu
44 |
45 | ```bash
46 | # run the docker container and expose port 443 and 8000
47 | # don't forget to map the volumes correctly as shown below
48 | # we use port 8000 to not collapse with port 80 which we need by server.go
49 | docker run --detach \
50 | --hostname gitlab.example.com \
51 | --publish 443:443 --publish 8000:80 \
52 | --restart always \
53 | --volume ~/Desktop/gitlab/config:/etc/gitlab \
54 | --volume ~/Desktop/gitlab/log:/var/log/gitlab \
55 | --volume ~/Desktop/gitlab/opt:/var/opt/gitlab \
56 | gitlab/gitlab-ce:latest
57 |
58 | # display real time logs for GitLab docker container
59 | docker logs --follow [CONTAINER_ID]
60 |
61 | # WAIT TILL IT FINISHES
62 |
63 | # open up localhost:8000
64 |
65 | # set up a new password, preferably something which uses
66 | # Uppercase, letters, numbers, alphanumeric characters
67 | # otherwise GitLab won't allow you to go further
68 | # something like: Pas$word123456
69 |
70 | # login with the credentials:
71 | # username: root
72 | # password: [PASSWORD_YOU_CREATED]
73 |
74 | # create a repository from the admin panel and name it `some-test`
75 |
76 | # clone the created repository on your local machine
77 | git clone http://localhost:8000/root/some-test.git
78 |
79 | # add the go pkg shown bellow and save it inside pkg.go
80 |
81 | git add -A
82 |
83 | git commit -m "initial commit"
84 |
85 | git push
86 |
87 | # input your username: root
88 | # input your password: [PASSWORD_YOU_CREATED]
89 |
90 | # DONE
91 | ```
92 |
93 | ###### `pkg.go`
94 | ```go
95 | package pkg // import "0.0.0.0/user/pkg"
96 |
97 | import "fmt"
98 |
99 | func New() {
100 | fmt.Println("Welcome to pkg! (GitLab - Docker)")
101 | }
102 | ```
103 |
104 | #### More info
105 |
106 | ***Note***: import path checking is disabled when using
107 | `Go modules` or `vendor` directory
108 |
109 | ```bash
110 | # displays useful information about import paths in Go
111 | go help importpath
112 |
113 | # displays useful information about Go specific env variables
114 | # i.e. GO111MODULE
115 | go help environment
116 | ```
117 |
118 | ## Resources 💎
119 |
120 | - [`go get` custom import path](https://jve.linuxwall.info/blog/index.php?post/2015/08/26/Hosting_Go_code_on_Github_with_custom_import_path)
121 | - [Remote import paths](https://golang.org/cmd/go/#hdr-Remote_import_paths)
122 | - [Custom import path checking](https://docs.google.com/document/d/1jVFkZTcYbNLaTxXD9OcGfn7vYv5hWtPx9--lTx1gPMs/edit)
123 | - [GitLab Docker](https://docs.gitlab.com/omnibus/docker/)
124 |
125 | ## FEEDBACK ⚗
126 |
127 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
128 |
129 | ## COMMUNITY 🙌
130 |
131 | [GopherTuts Discord](https://discord.gg/4sgecdh)
132 |
133 | ---
134 |
135 | Back to
136 | [Go Basics](https://github.com/gophertuts/go-basics)
137 |
138 |
139 |
--------------------------------------------------------------------------------
/custom-import-path/custom-path/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "0.0.0.0/user/pkg"
4 |
5 | func main() {
6 | pkg.New()
7 | }
8 |
--------------------------------------------------------------------------------
/custom-import-path/custom-path/server.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 | )
8 |
9 | const html = `
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | Nothing to see here; move along.
18 |
19 | `
20 |
21 | var projects = map[string]struct {
22 | vcs string
23 | remoteURL string
24 | }{
25 | "github": {
26 | vcs: "git",
27 | remoteURL: "https://github.com/steevehook/some-test",
28 | },
29 | "gitlab": {
30 | vcs: "git",
31 | remoteURL: "https://gitlab.com/steevehook/some-test",
32 | },
33 | "gitlab-docker": {
34 | vcs: "git",
35 | remoteURL: "http://localhost:8000/root/some-test.git",
36 | },
37 | "bitbucket-git": {
38 | vcs: "git",
39 | remoteURL: "https://bitbucket.org/steevehook/some-test-git",
40 | },
41 | // BitBucket says they will stop Mercurial support by Feb 2020. Be aware
42 | "bitbucket-hg": {
43 | vcs: "hg",
44 | remoteURL: "https://bitbucket.org/steevehook/some-test-hg",
45 | },
46 | }
47 |
48 | func main() {
49 | http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
50 | tpl := fmt.Sprintf(html, projects["github"].vcs, projects["gitlhub"].remoteURL)
51 | fmt.Fprint(w, tpl)
52 | })
53 | log.Fatal(http.ListenAndServe(":80", nil))
54 | }
55 |
--------------------------------------------------------------------------------
/custom-import-path/import-path-checking/README.md:
--------------------------------------------------------------------------------
1 | # Import path checking
2 |
3 | ## Overview
4 |
5 | This program proves how `import path checking` works
6 | when enabled from a certain package.
7 |
8 | ***Note***: this is a feature designed mainly for
9 | custom import paths which use `custom domains (hosts)`
10 | instead of fixed hosting services
11 | such as `GitHub`, `BitBucket`, `GitLab` and others.
12 |
13 | ```bash
14 | # NOT GOING TO WORK (COMPILE)
15 | # but the package will be downloaded inside
16 | # $GOPATH/src/github.com/steevehook/some-test
17 | go get github.com/steevehook/some-test
18 |
19 | # Will fail, because of wrong import path
20 | go run main.go
21 | ```
22 |
--------------------------------------------------------------------------------
/custom-import-path/import-path-checking/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/steevehook/some-test/pkg"
4 |
5 | func main() {
6 | // this won't even compile
7 | // because of import path checking
8 | pkg.New()
9 | }
10 |
--------------------------------------------------------------------------------
/custom-package-manager/Custom package manger.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/custom-package-manager/Custom package manger.key
--------------------------------------------------------------------------------
/custom-package-manager/README.md:
--------------------------------------------------------------------------------
1 | # Custom package manager
2 |
3 | ## Medium version 📖
4 |
5 | [Custom package manager in Go](https://medium.com/@gophertuts/packages-in-go-df5438123548)
6 |
7 | #### How to test
8 |
9 | ```bash
10 | # generate pkg-manager binary and places it inside $GOPATH/bin
11 | go install
12 |
13 | # export $GOPATH/bin and add it inside $PATH env variable
14 | echo "export GOBIN=$GOPATH/bin\nexport PATH=$GOBIN:$PATH" >> .bashrc
15 | echo "export GOBIN=$GOPATH/bin\nexport PATH=$GOBIN:$PATH" >> .zshrc
16 |
17 | # create a simple go project
18 | mkdir project-name
19 | touch go-pkg.json
20 | # or using
21 | pkg-manager init project-name
22 |
23 | # downloads all dependencies indicated in go-pkg.json
24 | pkg-manager get ./...
25 |
26 | # downloads the specified dependency and saves it inside in go-pkg.json
27 | # using either the version tag in format: 'v1.2.3'
28 | # or using the commit hash
29 | pkg-manager get github.com/user/repo@version
30 | pkg-manager get github.com/user/repo@GIT_COMMIT_HASH
31 | ```
32 |
33 | #### Useful info
34 |
35 | ```bash
36 | go help importpath
37 | ```
38 |
39 | #### Improvements
40 |
41 | - Add recursive dependency tree fetching
42 | - Add a lock file with detailed dependency tree
43 | - Add a caching mechanism and/or proxy mechanism
44 | - Implement Go's download protocol
45 | - Don't save git repositories, just the actual code
46 | - Add support for archives instead of VCS checkouts
47 | - Add the possibility to skip test files or non go files to save bandwidth
48 | - Add support for custom domains & custom import paths
49 | - Add support for multiple VCS systems
50 |
51 | ## Resources 💎
52 |
53 | - [Go 1.5 vendor experiment](https://go.googlesource.com/proposal/+/master/design/25719-go15vendor.md)
54 | - [Vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories)
55 | - [VGO module](https://research.swtch.com/vgo-module)
56 | - [Go project structure](https://vsupalov.com/go-folder-structure/)
57 | - [Go project layout](https://github.com/golang-standards/project-layout)
58 | - [Dep package manager](https://github.com/golang/dep)
59 | - [Project Athens - the download protocol](https://medium.com/@arschles/project-athens-the-download-protocol-2b346926a818)
60 | - [Go module proxy protocol](https://golang.org/cmd/go/#hdr-Module_proxy_protocol)
61 | - [Go module proxy - Fatih Arslan](https://arslan.io/2019/08/02/why-you-should-use-a-go-module-proxy/)
62 | - [Go proxies](https://roberto.selbach.ca/go-proxies/)
63 | - [Athens - GitHub project](https://medium.com/@arschles/project-athens-the-download-protocol-2b346926a818)
64 | - [Go module sum](https://sum.golang.org/)
65 |
66 | ## FEEDBACK ⚗
67 |
68 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
69 |
70 | ## COMMUNITY 🙌
71 |
72 | [GopherTuts Discord](https://discord.gg/4sgecdh)
73 |
74 | ---
75 |
76 | Back to
77 | [Go Basics](https://github.com/gophertuts/go-basics)
78 |
79 |
--------------------------------------------------------------------------------
/custom-package-manager/pkg-manager/downloader.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os"
6 | "path"
7 | "strings"
8 |
9 | "gopkg.in/src-d/go-git.v4"
10 | "gopkg.in/src-d/go-git.v4/plumbing"
11 | )
12 |
13 | const vendor = "vendor"
14 |
15 | func Download(deps map[string]string) {
16 | for dependency, version := range deps {
17 | _, err := os.Stat(vendor)
18 | if os.IsNotExist(err) {
19 | createVendor(dependency)
20 | } else {
21 | deleteVendor(dependency)
22 | createVendor(dependency)
23 | }
24 | repo, err := git.PlainClone(
25 | path.Join(".", vendor, dependency),
26 | false, &git.CloneOptions{
27 | URL: "https://" + dependency,
28 | Progress: os.Stdout,
29 | })
30 | if err != nil {
31 | log.Fatalf("%+v: %s", err, dependency)
32 | }
33 | checkout(repo, version)
34 | }
35 | }
36 |
37 | func createVendor(dependency string) {
38 | err := os.MkdirAll(
39 | path.Join(".", vendor, dependency),
40 | 0755,
41 | )
42 | if err != nil {
43 | log.Fatal(err)
44 | }
45 | }
46 |
47 | func deleteVendor(dependency string) {
48 | err := os.RemoveAll(path.Join(".", vendor, dependency))
49 | if err != nil {
50 | log.Fatal(err)
51 | }
52 | }
53 |
54 | func versionToHash(repo *git.Repository, version string) string {
55 | if version == "master" {
56 | head, _ := repo.Head()
57 | return head.String()
58 | }
59 | tags, _ := repo.Tags()
60 | for {
61 | tag, err := tags.Next()
62 | if err != nil {
63 | break
64 | }
65 | if strings.Contains(tag.Name().String(), version) {
66 | return tag.Hash().String()
67 | }
68 | }
69 | commits, _ := repo.CommitObjects()
70 | for {
71 | commit, err := commits.Next()
72 | if err != nil {
73 | break
74 | }
75 | if strings.Contains(commit.Hash.String(), version) {
76 | return commit.Hash.String()
77 | }
78 | }
79 | return ""
80 | }
81 |
82 | func checkout(repo *git.Repository, version string) {
83 | workTree, err := repo.Worktree()
84 | if err != nil {
85 | log.Fatal(err)
86 | }
87 | hash := versionToHash(repo, version)
88 | if hash == "" {
89 | cfg, _ := repo.Config()
90 | log.Fatalf(
91 | "no such version: '%s' for origin remote: '%s'",
92 | version,
93 | cfg.Remotes["origin"].URLs[0],
94 | )
95 | }
96 | if err = workTree.Checkout(&git.CheckoutOptions{
97 | Hash: plumbing.NewHash(versionToHash(repo, version)),
98 | }); err != nil {
99 | log.Fatal(err)
100 | }
101 | }
102 |
--------------------------------------------------------------------------------
/custom-package-manager/pkg-manager/go-pkg.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": {
3 | "github.com/julienschmidt/httprouter": "v1.3.0",
4 | "github.com/sirupsen/logrus": "v1.4.2",
5 | "github.com/stretchr/testify": "f35b8ab",
6 | "github.com/uber-go/zap": "master"
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/custom-package-manager/pkg-manager/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "os"
7 | "strings"
8 | )
9 |
10 | func main() {
11 | args := os.Args[1:]
12 | helpMsg := "\nUSAGE:" +
13 | "\npkg-manager help\t\t\t\t\t\t\t\t --- " +
14 | "displays this message\n" +
15 | "\npkg-manager init project-name\t\t\t\t\t\t\t --- " +
16 | "creates a new bare bones project\n" +
17 | "\npkg-manager get ./...\t\t\t\t\t\t\t\t --- " +
18 | "downloads all dependencies specified in 'go-pkg.json'\n" +
19 | "\npkg-manager get github.com/user1/repo@version github.com/user2/repo@version\t --- " +
20 | "downloads the mentioned list of dependencies using the git tag version and updates the go-pkg.json\n" +
21 | "\npkg-manager get github.com/user/repo@GIT_COMMIT_HASH\n" +
22 | "\npkg-manager get github.com/user/repo@GIT_COMMIT_HASH\t\t\t\t --- " +
23 | "downloads the mentioned list of dependencies using the git commit hash and updates the go-pkg.json\n"
24 | if len(args) > 0 && args[0] == "help" {
25 | fmt.Print(helpMsg)
26 | return
27 | }
28 |
29 | if len(args) < 2 {
30 | helpMsg = "Incorrect use of command\n" + helpMsg
31 | log.Fatal(helpMsg)
32 | }
33 |
34 | cmd := strings.TrimSpace(strings.ToLower(args[0]))
35 | cmdArgs := args[1:]
36 | m := NewManager([2]string{args[0], args[1]})
37 |
38 | switch {
39 | case cmd == "init" && len(cmdArgs) == 1:
40 | fmt.Println("=== creating a bare bones project ===")
41 | CreateProject(cmdArgs[0])
42 | UpdateGoPkg(m, map[string]string{})
43 | case cmd == "get" && cmdArgs[0] == "./...":
44 | fmt.Println("=== downloading all dependencies from go-pkg.json ===")
45 | Download(m.Dependencies)
46 | case cmd == "get" && cmdArgs[0] != "./...":
47 | deps := NewDependencies(cmdArgs)
48 | fmt.Println("=== downloading specified dependencies ===")
49 | Download(deps)
50 | fmt.Println("=== updating go-pkg.json ===")
51 | UpdateGoPkg(m, deps)
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/custom-package-manager/pkg-manager/manager.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "bytes"
5 | "encoding/json"
6 | "fmt"
7 | "io/ioutil"
8 | "log"
9 | "os"
10 | "path"
11 | "strings"
12 | )
13 |
14 | type Manager struct {
15 | WorkDir string `json:"-"`
16 | Dependencies map[string]string `json:"dependencies"`
17 | }
18 |
19 | func NewManager(args [2]string) Manager {
20 | if strings.TrimSpace(strings.ToLower(args[0])) == "init" {
21 | return Manager{
22 | WorkDir: args[1],
23 | Dependencies: map[string]string{},
24 | }
25 | }
26 | var m Manager
27 | err := json.Unmarshal(readGoPkg(), &m)
28 | if err != nil {
29 | log.Fatal(err)
30 | }
31 | return m
32 | }
33 |
34 | func NewDependencies(packageList []string) map[string]string {
35 | deps := map[string]string{}
36 | for _, dep := range packageList {
37 | ds := strings.Split(dep, "@")
38 | pkg := ds[0]
39 | var version string
40 | if len(ds) < 2 {
41 | version = "master"
42 | } else {
43 | version = ds[1]
44 | }
45 | deps[pkg] = version
46 | }
47 | return deps
48 | }
49 |
50 | func CreateProject(projectName string) {
51 | fmt.Println("=== creating project directory ===")
52 | err := os.Mkdir(path.Join(".", projectName), 0755)
53 | if err != nil {
54 | log.Fatalf("could not create project directory\n%+v", err)
55 | }
56 | fmt.Println("=== creating empty go-pkg.json file ===")
57 | _, err = os.Create(path.Join(".", projectName, "go-pkg.json"))
58 | if err != nil {
59 | log.Fatalf("could not create go-pkg.json file\n%+v", err)
60 | }
61 | }
62 |
63 | func UpdateGoPkg(m Manager, newDeps map[string]string) {
64 | for dep, ver := range newDeps {
65 | m.Dependencies[dep] = ver
66 | }
67 | // JSON marshall the manager
68 | bs, _ := json.Marshal(m)
69 | bs = append(bs, '\n')
70 |
71 | // write the new result to the file
72 | err := ioutil.WriteFile(path.Join(".", m.WorkDir, "go-pkg.json"), prettyPrint(bs), 0755)
73 | if err != nil {
74 | log.Fatal(err)
75 | }
76 | }
77 |
78 | func readGoPkg() []byte {
79 | file, err := os.Open("go-pkg.json")
80 | if err != nil {
81 | log.Fatalf("go-pkg.json not found, create one\n%+v", err)
82 | }
83 | bs, _ := ioutil.ReadAll(file)
84 | return bs
85 | }
86 |
87 | func prettyPrint(b []byte) []byte {
88 | var out bytes.Buffer
89 | _ = json.Indent(&out, b, "", " ")
90 | return out.Bytes()
91 | }
92 |
--------------------------------------------------------------------------------
/go-commands.md:
--------------------------------------------------------------------------------
1 | # Go useful commands explained
2 |
3 | Here are a list of *daily Go commands* used by developers, which will
4 | help you stay productive if you know about them.
5 |
6 | ## Frequently used commands
7 |
8 | ### `go get`
9 |
10 | Downloads *third party packages*, by *git* cloning the repository
11 | and installing binaries if any
12 |
13 | Example:
14 | ```bash
15 | # downloads the "errors" package
16 | go get github.com/pkg/errors
17 |
18 | # downloads and updates the "errors" package
19 | go get -u github.com/pkg/errors
20 |
21 | # downloads all packages that the current project imports/uses
22 | go get ./...
23 | ```
24 |
25 | ### `go run`
26 |
27 | Compiles and builds the project, after which it generates a binary in
28 | a temporary location then executes that binary
29 |
30 | Example:
31 | ```bash
32 | # Compiles "main.go" and executes the binary
33 | go run main.go
34 |
35 | # Compiles "main.go" and "package.go" and executes the binary
36 | go run main.go package.go
37 |
38 | # Compiles all ".go" files in CWD and executes the binary
39 | go run *.go
40 | ```
41 |
42 | ### `go build`
43 |
44 | Compiles and creates executable binary from source code
45 |
46 | Example:
47 | ```bash
48 | go build
49 |
50 | go build -o executable-name
51 | ```
52 |
53 | ### `go test`
54 |
55 | Runs all Go tests which are located inside *_test.go* files from
56 | current working directory
57 |
58 | Example:
59 | ```bash
60 | go test ./...
61 | ```
62 |
63 | ## Other useful commands
64 |
65 | ### `go install`
66 |
67 | Compiles Go code from binary.go and creates a binary called
68 | "bin" then places it inside `$GOPATH/bin` directory
69 |
70 | In order for this to work the file need to in **package main**
71 | and have a **main** function
72 |
73 | Example:
74 | ```bash
75 | go install bin.go
76 | ```
77 |
78 | ### `go fmt`
79 |
80 | Formats all Go code from current working directory
81 |
82 | Example:
83 | ```bash
84 | go fmt ./...
85 | ```
86 |
87 | ### `go vet`
88 |
89 | Checks for potential Go issues in current working directory
90 |
91 | Example:
92 | ```bash
93 | go vet ./...
94 | ```
95 |
96 | ### `go env`
97 |
98 | Displays all environment variables that Go uses and their values
99 |
100 | ### `go help`
101 |
102 | Displays a list of all available *Go commands*. Have fun and play
103 | around with them
104 |
105 | For more info about Go commands check out
106 | [Go Commands](https://golang.org/cmd/go/)
107 |
108 | Back to
109 | [Go Basics](https://github.com/gophertuts/go-basics)
110 |
--------------------------------------------------------------------------------
/go-environment-variables/README.md:
--------------------------------------------------------------------------------
1 | # Environment variables in Go
2 |
--------------------------------------------------------------------------------
/go-learning-resources/Go Resources.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-learning-resources/Go Resources.key
--------------------------------------------------------------------------------
/go-learning-resources/Go Resources.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-learning-resources/Go Resources.pdf
--------------------------------------------------------------------------------
/go-learning-resources/Go Resources.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-learning-resources/Go Resources.pptx
--------------------------------------------------------------------------------
/go-learning-resources/README.md:
--------------------------------------------------------------------------------
1 | # Go Resources
2 |
3 | ## Blog posts & Docs
4 |
5 | A good place for reading articles, blog posts & practicing Go by example
6 | The place that really takes you from zero to hero in no time
7 | I highly recommend checking these first, they will tremendously
8 | boost your development and save you a lot of time
9 |
10 | - [GoTour](https://tour.golang.org/welcome/1)
11 | - [Effective Go](https://golang.org/doc/effective_go.html)
12 | - [Go Blog](https://blog.golang.org/)
13 | - [Go Doc](https://godoc.org/)
14 | - [Golang Spec](https://golang.org/)
15 | - [Go by Example](https://gobyexample.com/)
16 | - [Go Proverbs](https://go-proverbs.github.io/)
17 | - [Awesome Go](https://github.com/avelino/awesome-go)
18 | - [Idiomatic Go](https://dmitri.shuralyov.com/idiomatic-go)
19 | - [Idiomatic Go - Sourcegraph](https://about.sourcegraph.com/go/idiomatic-go)
20 | - [Dave Cheney](https://dave.cheney.net/)
21 | - [Medium Golang](https://medium.com/search?q=golang)
22 |
23 | ## Discussions & Q&A
24 |
25 | A good place to keep in touch with the community. Talk & share
26 | different solutions or help others solve their difficulties
27 |
28 | - [Golang Redit](https://www.reddit.com/r/golang)
29 | - [Go Forum](https://forum.golangbridge.org/)
30 |
31 | ## Twitter influencers
32 |
33 | Having mentors is insanely important and can drive the wheel so much
34 | faster in software engineering. Make sure to follow the best of the
35 | best in the community and keep up with the latest news
36 |
37 | - [@davecheney](https://twitter.com/@davecheney)
38 | - [@rob_pike](https://twitter.com/@rob_pike)
39 | - [@_rsc](https://twitter.com/@_rsc)
40 | - [@cool_golang](https://twitter.com/@cool_golang)
41 | - [@Cassandraoid](https://twitter.com/@Cassandraoid)
42 | - [@GopherCon](https://twitter.com/@GopherCon)
43 | - [@welovegolang](https://twitter.com/@welovegolang)
44 | - [@golangprojects](https://twitter.com/@golangprojects)
45 | - [@GopherAcademy](https://twitter.com/@GopherAcademy)
46 | - [@golangweekly](https://twitter.com/@golangweekly)
47 | - [@martinfowler](https://twitter.com/@martinfowler)
48 | - [@RealGophersShip](https://twitter.com/@RealGophersShip)
49 | - [@GopherTuts](https://twitter.com/@GopherTuts)
50 | - [@francesc](https://twitter.com/@francesc)
51 | - [@Todd_McLeod](https://twitter.com/@Todd_McLeod)
52 |
53 | ## Books
54 |
55 | These are books which I've read, reading at the moment or books which
56 | are the best known in the community. There's no better explanation than
57 | one in a book. Grab some coffee and read some cool Go books ☕☕☕
58 |
59 | - [The Go Programming Language](https://www.amazon.com/Programming-Language-Addison-Wesley-Professional-Computing/dp/0134190440)
60 | - [The way to Go](https://archive.org/details/TheWayToGo)
61 | - [Go in Action](https://www.amazon.com/Go-Action-William-Kennedy/dp/1617291781)
62 | - [Go in Practice](https://www.amazon.com/gp/product/1633430073/ref=x_gr_w_bb?ie=UTF8&tag=x_gr_w_bb-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=1633430073&SubscriptionId=1MGPYB6YW3HWK55XCGG2)
63 | - [Other Books](https://github.com/golang/go/wiki/Books)
64 |
65 | ## YouTube channels
66 |
67 | For people who like learning visually and preferably free good video
68 | tutorials seems like an impossible task to accomplish. YouTube is
69 | so full of videos and until you find something good, it takes time
70 | or you simply don't find.
71 |
72 | Here are a list of channels I consider are the best for learning Go
73 | and I myself have subscribed to:
74 |
75 | - [JustForFunc](https://www.youtube.com/channel/UC_BzFbxG2za3bp5NRRRXJSw)
76 | - [Gopher Academy](https://www.youtube.com/channel/UCx9QVEApa5BKLw9r8cnOFEA/feed)
77 | - [GopherCon UK](https://www.youtube.com/channel/UC9ZNrGdT2aAdrNbX78lbNlQ)
78 | - [Coding Tech](https://www.youtube.com/channel/UCtxCXg-UvSnTKPOzLH4wJaQ)
79 | - [The Go Programming language](https://www.youtube.com/user/gocoding)
80 | - [GOTO Conferences](https://www.youtube.com/user/GotoConferences)
81 | - [Russ Cox](https://www.youtube.com/user/rscgolang)
82 | - [Learn to Code - Todd McCleod](https://www.youtube.com/user/toddmcleod)
83 |
84 | ## Udemy courses
85 |
86 | YouTube or other similar free video services can be overwhelming
87 | and cluttered many times. You don't just find good free videos, that's
88 | why the best videos are those organized inside courses
89 |
90 | Of course paid courses, but let's be serious this is like the cheapest
91 | platform where you get lifetime access to courses and updates
92 |
93 | These are the courses I've finished when I first started to learn Go
94 | and recommend doing if you're like me and like learning from
95 | videos
96 |
97 | - [Learn How To Code: Google's Go (golang) Programming Language - T. McCleod](https://www.udemy.com/course/learn-how-to-code/)
98 | - [Web Development w/ Google’s Go (golang) Programming Language - T. McCleod](https://www.udemy.com/course/go-programming-language/)
99 | - [Go: The Complete Developer's Guide (Golang) - Stephen Grider](https://www.udemy.com/course/go-the-complete-developers-guide/)
100 |
101 | ## GitHub
102 |
103 | GitHub is the place where Open Source is. It's also the place where
104 | are the latest changes, nothing is more actual the master branch
105 |
106 | Wanna be in touch with what's happening in the Go world, have a
107 | look at these repositories full of examples and best practices on
108 | writing idiomatic Go code
109 |
110 | - [Go Code Review Comments](https://github.com/golang/go/wiki/CodeReviewComments)
111 | - [Awesome Go](https://github.com/avelino/awesome-go)
112 | - [Go Books](https://github.com/golang/go/wiki/Books)
113 | - [Go Training Ardan Labs](https://github.com/ardanlabs/gotraining)
114 | - [Go Training Todd McCleod](https://github.com/GoesToEleven/GolangTraining)
115 | - [Go Web Dev](https://github.com/GoesToEleven/golang-web-dev)
116 | - [Go GH Organization](https://github.com/golang)
117 |
118 | ## Mail subscriptions
119 |
120 | The best way to be up to date is by letting someone notify you
121 | We all use mail boxes, so that the best way to stay tuned and keep in
122 | touch with the latest trends in Go
123 |
124 | Be careful and stay away from spamming your Inbox
125 |
126 | - [Golang Weekly](https://golangweekly.com/)
127 | - [Awesome Go](https://go.libhunt.com/newsletter)
128 | - [Jon Calhoun](https://www.calhoun.io/)
129 |
130 | Hope this was useful. Now go ahead and use this knowledge! 🚀🚀🚀
131 |
132 | ## FEEDBACK ⚗
133 |
134 | [GopherTuts TypeForm](https://gophertuts.typeform.com/to/j2CJmC)
135 |
136 | ## COMMUNITY 🙌
137 |
138 | [GopherTuts Discord](https://discord.gg/4sgecdh)
139 |
140 | ---
141 |
142 | Back to
143 | [Go Basics](https://github.com/gophertuts/go-basics)
144 |
145 |
146 |
--------------------------------------------------------------------------------
/go-module-proxy/Go module proxy.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-module-proxy/Go module proxy.key
--------------------------------------------------------------------------------
/go-module-proxy/README.md:
--------------------------------------------------------------------------------
1 | # Go module proxy
2 |
3 |
4 | ## Medium version 📖
5 |
6 | [Go module proxy](https://medium.com/@gophertuts/packages-in-go-df5438123548)
7 |
8 | ### More info
9 |
10 | ```bash
11 | go help importpath
12 |
13 | go help goproxy
14 | ```
15 |
16 | ## Resources 💎
17 |
18 | - [Go 1.5 vendor experiment](https://go.googlesource.com/proposal/+/master/design/25719-go15vendor.md)
19 | - [Vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories)
20 | - [VGO module](https://research.swtch.com/vgo-module)
21 | - [Athens project](https://docs.gomods.io)
22 | - [Athens project - GitHub](https://github.com/gomods/athens)
23 | - [Athens docker image](https://docs.gomods.io)
24 | - [Go project structure](https://vsupalov.com/go-folder-structure/)
25 | - [Go project layout](https://github.com/golang-standards/project-layout)
26 |
27 | ## FEEDBACK ⚗
28 |
29 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
30 |
31 | ## COMMUNITY 🙌
32 |
33 | [GopherTuts Discord](https://discord.gg/4sgecdh)
34 |
35 | ---
36 |
37 | Back to
38 | [Go Basics](https://github.com/gophertuts/go-basics)
39 |
40 |
41 |
--------------------------------------------------------------------------------
/go-modules/@latest/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/Go modules.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-modules/Go modules.key
--------------------------------------------------------------------------------
/go-modules/README.md:
--------------------------------------------------------------------------------
1 | # Go Modules
2 |
3 | ### `$GOPATH`
4 |
5 | ```bash
6 | # display useful information about $GOPATH
7 | go help gopath
8 | ```
9 |
10 | ### `$GOPRIVATE`
11 |
12 | ```bash
13 | # Lists all available packages inside $GOPATH
14 | # OR All packages inside current module
15 | # if env variable GO111MODULE=on
16 | go list all
17 |
18 | # Lists all std lib packages and its sub packages
19 | # Works the same as `go list all`
20 | go list std
21 |
22 | # Lists all cmd packages and its sub packages
23 | # Works the same as `go list all`
24 | go list cmd
25 |
26 | # Lists all available local packages in CWD
27 | go list ./...
28 |
29 | # Lists all imported (local) packages in a JSON format
30 | go list -json ./...
31 |
32 | # Displays useful information about import paths
33 | go help importpath
34 | ```
35 |
36 | ## Resources 💎
37 |
38 | - [Migrating to Go modules](https://blog.golang.org/migrating-to-go-modules)
39 | - [VGO module](https://research.swtch.com/vgo-module)
40 | - [Module configuration (private modules)](https://golang.org/cmd/go/#hdr-Module_configuration_for_non_public_modules)
41 |
42 | ## FEEDBACK ⚗
43 |
44 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
45 |
46 | ## COMMUNITY 🙌
47 |
48 | [GopherTuts Discord](https://discord.gg/4sgecdh)
49 |
50 | ---
51 |
52 | Back to
53 | [Go Basics](https://github.com/gophertuts/go-basics)
54 |
55 |
56 |
--------------------------------------------------------------------------------
/go-modules/basic-http/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/download/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/go-mod-tidy/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/go111module/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/incompatible-pkg-versions/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/migration-from-dep/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/outside-gopath/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-modules/vendor-directory/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/go-program-anatomy/Go program anatomy.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-program-anatomy/Go program anatomy.key
--------------------------------------------------------------------------------
/go-program-anatomy/Go program anatomy.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-program-anatomy/Go program anatomy.pdf
--------------------------------------------------------------------------------
/go-program-anatomy/Go program anatomy.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/go-program-anatomy/Go program anatomy.pptx
--------------------------------------------------------------------------------
/go-program-anatomy/README.md:
--------------------------------------------------------------------------------
1 | # Go program anatomy:
2 |
3 | ## Prerequisites
4 |
5 | - Install Docker for your platform by checking
6 | [Docker Installation](https://docs.docker.com/install/)
7 |
8 | ## How to test `go-build`
9 |
10 | Create a Docker container to simulate the Linux environment
11 | FYI: It's easier to run it inside Docker then spinning up a VM ;)
12 |
13 | ```bash
14 | # download the repository with src code if you haven't already
15 | go get github.com/gophertuts/go-basics
16 |
17 | # cd into go-build directory on your machine
18 | cd $GOPATH/src/github.com/gophertuts/go-basics/go-program-anatomy/go-build
19 | ```
20 |
21 | ```bash
22 | # generate the binary
23 | go build
24 | ```
25 |
26 | ```bash
27 | # spin up a docker container that simulates linux OS with Go runtime support
28 | docker run --rm -it -v $(pwd):/go/src/github.com/gophertuts/go-basics/go-program-anatomy/go-build golang
29 | ```
30 |
31 | ```bash
32 | # cd into $GOPATH and run the generated binary
33 | cd /go/src/github.com/gophertuts/go-basics/go-program-anatomy/go-build
34 | ./go-build
35 | ```
36 |
37 | ## How to test `runtime-vs-buildtime`
38 |
39 | ```bash
40 | # cd into go-build directory on your machine
41 | cd $GOPATH/src/github.com/gophertuts/go-basics/go-program-anatomy/runtime-vs-buildtime
42 | ```
43 |
44 | ```bash
45 | # generate the binary
46 | env GOOS=linux GOARCH=386 GOHOSTOS=linux GOHOSTARCH=386 \
47 | go build -ldflags \
48 | "-X main.hostOS=$(go env GOHOSTOS) -X main.hostArch=$(go env GOHOSTARCH)"
49 | ```
50 |
51 | ```bash
52 | # spin up a docker container that simulates linux OS with Go runtime support
53 | docker run --rm -it -v $(pwd):/go/src/github.com/gophertuts/go-basics/go-program-anatomy/runtime-vs-buildtime golang
54 | ```
55 |
56 | ```bash
57 | # cd into $GOPATH and run the generated binary
58 | cd /go/src/github.com/gophertuts/go-basics/go-program-anatomy/runtime-vs-buildtime
59 | ./runtime-vs-buildtime
60 | ```
61 |
62 | #### Note:
63 |
64 | `$GOOS` and `$GOARCH` are evaluated at compile time and saved as constants
65 | inside `runtime.GOOS` and `runtime.GOARCH`
66 |
67 | Also keep in mind that if `$GOOS` and `$GOARCH` are not set, the
68 | default values will be taken from `$GOHOSTOS` and `$GOHOSTARCH`
69 | which by the way `CANNOT` be changed at `compile/build time`
70 |
71 |
72 | Play around with different `GOOS` & `GOARCH` values, here are some examples:
73 |
74 | - `env GOOS=linux GOARCH=386 go build`
75 | - `env GOOS=linux GOARCH=amd64 go build`
76 | - `env GOOS=darwin GOARCH=386 go build`
77 | - `env GOOS=darwin GOARCH=amd64 go build`
78 |
79 | ## Resources 💎
80 |
81 | - [Go Build](https://golang.org/pkg/go/go-build/)
82 | - [Go supported OS & Architectures](https://gist.github.com/asukakenji/f15ba7e588ac42795f421b48b8aede63)
83 | - [Go source code](https://golang.org/src/)
84 |
85 | ## FEEDBACK ⚗
86 |
87 | [GopherTuts TypeForm](https://gophertuts.typeform.com/to/j2CJmC)
88 |
89 | ## COMMUNITY 🙌
90 |
91 | [GopherTuts Discord](https://discord.gg/4sgecdh)
92 |
93 | ---
94 |
95 | Back to
96 | [Go Basics](https://github.com/gophertuts/go-basics)
97 |
98 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/bip_darwin_386.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func bip() {
6 | fmt.Println("Bip from Darwin 32 bit")
7 | }
8 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/bip_darwin_amd64.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func bip() {
6 | fmt.Println("Bip from Darwin 64 bit")
7 | }
8 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/bip_linux_386.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func bip() {
6 | fmt.Println("Bip from Linux 32 bit")
7 | }
8 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/bip_linux_amd64.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func bip() {
6 | fmt.Println("Bip from Linux 64 bit")
7 | }
8 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/good-bye-darwin-386.go:
--------------------------------------------------------------------------------
1 | // +build darwin,386
2 |
3 | package main
4 |
5 | import "fmt"
6 |
7 | func goodBye() {
8 | fmt.Println("Good bye from Darwin 32 bit")
9 | }
10 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/good-bye-darwin-amd64.go:
--------------------------------------------------------------------------------
1 | // +build darwin,amd64
2 |
3 | package main
4 |
5 | import "fmt"
6 |
7 | func goodBye() {
8 | fmt.Println("Good bye from Darwin 64 bit")
9 | }
10 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/good-bye-linux-386.go:
--------------------------------------------------------------------------------
1 | // +build linux,386
2 |
3 | package main
4 |
5 | import "fmt"
6 |
7 | func goodBye() {
8 | fmt.Println("Good bye from Linux 32 bit")
9 | }
10 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/good-bye-linux-amd64.go:
--------------------------------------------------------------------------------
1 | // +build linux,amd64
2 |
3 | package main
4 |
5 | import "fmt"
6 |
7 | func goodBye() {
8 | fmt.Println("Good bye from Linux 64 bit")
9 | }
10 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/greet_darwin.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func greet() {
6 | fmt.Println("Greetings from OSX")
7 | }
8 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/greet_linux.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func greet() {
6 | fmt.Println("Greetings from Linux")
7 | }
8 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | func main() {
4 | hello()
5 | greet()
6 | bip()
7 | goodBye()
8 | }
9 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/welcome-linux.go:
--------------------------------------------------------------------------------
1 | // +build linux
2 |
3 | package main
4 |
5 | import "fmt"
6 |
7 | func hello() {
8 | fmt.Println("Welcome to Linux")
9 | }
10 |
--------------------------------------------------------------------------------
/go-program-anatomy/go-build/welcome-osx.go:
--------------------------------------------------------------------------------
1 | // +build darwin
2 |
3 | package main
4 |
5 | import "fmt"
6 |
7 | func hello() {
8 | fmt.Println("Welcome to OSX")
9 | }
10 |
--------------------------------------------------------------------------------
/go-program-anatomy/program-flow/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | _ "github.com/gophertuts/go-basics/go-program-anatomy/program-flow/pkg1"
7 | )
8 |
9 | const (
10 | mc = "const"
11 | )
12 |
13 | var (
14 | mv = mc + ":var"
15 | )
16 |
17 | func init() {
18 | mv += ":init"
19 | }
20 |
21 | func main() {
22 | mv += ":main"
23 | fmt.Println("package main: mv:", mv)
24 | }
25 |
--------------------------------------------------------------------------------
/go-program-anatomy/program-flow/pkg1/pkg1.go:
--------------------------------------------------------------------------------
1 | package pkg1
2 |
3 | import (
4 | "fmt"
5 |
6 | // pkg2 side effects (init)
7 | _ "github.com/gophertuts/go-basics/go-program-anatomy/program-flow/pkg2"
8 | )
9 |
10 | const (
11 | c1 = 1
12 | // other consts
13 | )
14 |
15 | var (
16 | v1 = c1
17 | // other vars
18 | )
19 |
20 | func init() {
21 | fmt.Println("package pkg1: v1:", v1)
22 | }
23 |
--------------------------------------------------------------------------------
/go-program-anatomy/program-flow/pkg2/pkg2.go:
--------------------------------------------------------------------------------
1 | package pkg2
2 |
3 | import (
4 | "fmt"
5 |
6 | // pkg3 side effects (init)
7 | _ "github.com/gophertuts/go-basics/go-program-anatomy/program-flow/pkg3"
8 | )
9 |
10 | const (
11 | c2 = 10
12 | // other consts
13 | )
14 |
15 | var (
16 | v2 = c2
17 | // other vars
18 | )
19 |
20 | func init() {
21 | fmt.Println("package pkg2: v2:", v2)
22 | }
23 |
--------------------------------------------------------------------------------
/go-program-anatomy/program-flow/pkg3/pkg3.go:
--------------------------------------------------------------------------------
1 | package pkg3
2 |
3 | import "fmt"
4 |
5 | func init() {
6 | fmt.Println("package pkg3: v3:", v3)
7 | }
8 |
9 | // not in expected order
10 | var (
11 | v3 = c3
12 | // other vars
13 | )
14 |
15 | const (
16 | c3 = 100
17 | // other consts
18 | )
19 |
--------------------------------------------------------------------------------
/go-program-anatomy/runtime-vs-buildtime/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "runtime"
6 | )
7 |
8 | var (
9 | hostOS string
10 | hostArch string
11 | )
12 |
13 | func main() {
14 | fmt.Println("runtime values:", runtime.GOOS, runtime.GOARCH)
15 | fmt.Println("build time values:", hostOS, hostArch)
16 | }
17 |
--------------------------------------------------------------------------------
/go-workspace.md:
--------------------------------------------------------------------------------
1 | # Go WORKSPACE & dependency management explained
2 |
3 | Most of Go projects have a specific structure, which from project to project
4 | is pretty much the same. The project normally lives in `$GOPATH` location,
5 | which is the process developers do, right after installing Go binary.
6 |
7 | Right after installing Go binary, it is recommended to correctly set
8 | your `$GOPATH` variable, which most of the times, is set to
9 | `$HOME/go`
10 |
11 | The project layout represented below makes more sense once you start
12 | using third party packages, or your own packages.
13 |
14 | Traditionally third party packages which are hosted remotely
15 | are usually installed using `go get` tool.
16 |
17 | So for example installing `errors` package by `davecheney`
18 | you simply run:
19 | ```bash
20 | go get github.com/pkg/errors
21 | ```
22 |
23 | This command will reach `github.com/pkg/errors` and place the source code
24 | which will download inside `$GOPATH/src/github.com/pkg/errors`
25 |
26 | If the package contains a main function it will also run
27 | `go install` and create a binary for the downloaded package
28 |
29 | #### Go project layout:
30 | ```
31 | ├── $GOPATH/
32 | │ ├── src/
33 | │ │ ├── github.com/
34 | │ │ │ ├── organization/
35 | │ │ │ │ ├── project1/
36 | │ │ │ │ └── project2/
37 | │ │ │ ├── user1/
38 | │ │ │ │ ├── project1/
39 | │ │ │ │ └── project2/
40 | │ │ │ ├── pgk/
41 | │ │ │ └── └── errors/
42 | │ │ ├── gitlab.com/
43 | │ │ │ ├── organization/
44 | │ │ │ │ ├── project1/
45 | │ │ │ │ └── project2/
46 | │ │ │ ├── user1/
47 | │ │ │ │ ├── project1/
48 | │ │ │ │ └── project2/
49 | │ │ │ ├── user2/
50 | │ │ │ │ ├── project1/
51 | │ │ │ └── └── project2/
52 | │ │ ├── golang.org/
53 | │ │ │ ├── x/
54 | │ │ │ │ ├── crypto/
55 | │ │ │ │ ├── lint/
56 | │ │ │ └── └── sys/
57 | │ ├── bin/
58 | │ │ ├── goimports
59 | │ │ ├── golint
60 | │ │ ├── binary1
61 | │ │ └── binary2
62 | │ ├── pkg/
63 | │ │ ├── darwin_amd64/
64 | │ │ │ ├── github.com/
65 | │ │ │ │ ├── uber-go/
66 | │ │ │ │ │ └── atomic.a
67 | │ │ │ │ ├── user1/
68 | │ │ │ │ │ ├── package1/
69 | │ │ │ └── └── └── package2/
70 | │ │ ├── mod/
71 | │ │ │ ├── github.com/
72 | │ │ │ │ ├── uber-go/
73 | │ │ │ │ │ └── zap@1.8.0
74 | │ │ │ │ │ └── zap@1.9.1
75 | │ │ │ └── └── └── ...
76 | │ │ ├── dep/
77 | │ │ │ ├── sources/
78 | │ │ │ │ ├── https---github.com-pkg-errors/
79 | │ │ │ │ │ ├── errors.go
80 | │ │ │ │ │ ├── errors_test.go
81 | │ │ │ │ │ └── ...
82 | │ │ │ │ ├── https---github.com-user1-project1/
83 | │ │ │ │ │ ├── file1.go
84 | │ │ │ │ │ ├── file1_test.go
85 | │ │ ├── ├── ├── └── ...
86 | │ │ │ │ ├── https---github.com-user2-project1/
87 | │ │ │ │ │ ├── file1.go
88 | │ │ │ │ │ ├── file1_test.go
89 | │ │ │ │ │ ├── file2.go
90 | │ │ │ │ │ ├── file2_test.go
91 | │ │ └── └── └── └── ...
92 | │ └──
93 | └──
94 | ```
95 |
96 | ### `$GOPATH`
97 |
98 | `$GOPATH` is the location of Go workspace. In other words, the place
99 | where all Go projects and third party packages will live.
100 |
101 | It is recommended to set `$GOPATH` right after installing Go binary.
102 | Also it is not recommended to have multiple `$GOPATH` variables
103 | when switching projects.
104 |
105 | By simply placing this inside your `.profile` or `.bashrc` or
106 | `.zshrc` depending on which SHELL you use it should set `$GOPATH` correctly
107 |
108 | ```bash
109 | export GOPATH=$HOME/go
110 | ```
111 |
112 | Go `1.11` introduces modules, which allows users to create projects
113 | and libraries outside `$GOPATH` location.
114 |
115 | Most of the projects out there use `$GOPATH` and it's gonna stay there for a while.
116 | Go modules are something new and definitely worth giving a try.
117 |
118 | They seem to be a good feet for libraries, where less dependencies
119 | are usually required, because Go modules come, with their own
120 | configuration file and a verbosity layer
121 |
122 | ### `src`
123 |
124 | Represents the directory where all the projects' source code and
125 | third party packages will live. So when making a reference to a
126 | third party package or one of your local packages, it will
127 | reference `src` directory.
128 |
129 | The source for a package with the import path `"X/Y/Z"` lives in the directory
130 | `$GOPATH/src/X/Y/Z`
131 |
132 | So importing `errors` package by `davecheney` will look something like:
133 |
134 | ```go
135 | import (
136 | "os"
137 | "net/http"
138 |
139 | "github.com/pkg/errors"
140 |
141 | "github.com/username/project/package"
142 | )
143 | ```
144 |
145 | All of the references to `github.com/...` will be resolved down to
146 | `src` directory where `github.com` lives.
147 |
148 | Notice also that packages like: `os` and `net/http` do not require
149 | this bloated prefix. It's because they are part of standard library.
150 |
151 | Even local packages are referenced using this long path prefix,
152 | hence `github.com/username/project/package`
153 |
154 | Downloading third party packages using `go get` tool, will store packages
155 | in the same `src` location using `git` to clone the repository.
156 |
157 | ### `bin`
158 |
159 | Represents the location where all Go binaries are stored. Usually
160 | when downloading a package using `go get` or when we manually run
161 | `go install` inside the location where we have a main package, in
162 | both cases these operations will result in creating a binary and
163 | storing it inside `$GOPATH/bin` directory which is also represented
164 | by `$GOBIN` environment variable.
165 |
166 | The binary for a command whose source is in `$GOPATH/src/A/B` lives in
167 | `$GOPATH/bin/B`
168 |
169 | Also if `$GOBIN` variable is included in path, you can run any
170 | compiled binary by simply typing their name.
171 |
172 | So a good practice after installing Go binary is to include
173 | `$GOBIN` inside `$PATH` variable so, every binary is easily accessible.
174 |
175 | By simply placing this inside your `.profile` or `.bashrc` or
176 | `.zshrc` depending on which SHELL you use it should set `$GOBIN` correctly.
177 |
178 | ```bash
179 | export GOBIN=$GOPATH/bin
180 | export PATH=$PATH:/$GOBIN
181 | ```
182 |
183 | ### `pkg`
184 |
185 | Represents the location for package archives, where binaries
186 | needed for a certain package import are stored. If a package is required by
187 | `$GOPATH/src/github.com/username/project` then there is likely a chance,
188 | that package will be stored as an archive file inside `$GOPATH/pkg`
189 |
190 | The binary for a package with the import path `"X/Y/Z"` lives in
191 | `$GOPATH/pkg/$GOOS_$GOARCH/X/Y/Z.a`
192 |
193 | ### `vendor` directory
194 |
195 | The `vendor` directory inside `$GOPATH/host/username/project` is
196 | recognized as a special directory by Go binary tool. And there are
197 | plenty of tools such as `dep` which serve the purpose of package
198 | management.
199 |
200 | `$GOPATH` alone works nice, but when it comes to using different
201 | versions of packages inside a project it fails to do so.
202 |
203 | Because by default `go get` tool will fetch the latest code from `master`
204 | branch and that may be an issue is all of th sudden an issue/bug was
205 | introduced in the latest version of a third party package, which
206 | likely happens very often in the modern web development.
207 |
208 | When Go encounters an import path like `"X/Y/Z"`, it will
209 | try to resolve it in several ways. It will look for a `vendor`
210 | directory first, if it finds any, it will resolve the package from
211 | there, if not it will continue to look in `$GOPATH`.
212 |
213 | For all this `vendor` directory magic to work, it is required
214 | that your project is inside `$GOPATH`, otherwise this will
215 | not work.
216 |
217 | ### `dep`
218 |
219 | `Dep` is a modern Go package manager. For a long period of time
220 | Go did not have any package managers. Meaning that the imported code
221 | from third party packages was always latest version of it.
222 |
223 | Any issue or bug introduced in the third party package would directly affect
224 | the Go project without a way to rollback. Because that was a frequent
225 | problem the community emerged with tools like`glide` and `dep` which are
226 | package managers to address this issue.
227 |
228 | To install `dep` check out the
229 | [Installation Guide](https://golang.github.io/dep/docs/installation.html)
230 |
231 | Running `dep init` will get you started very quickly by generating
232 | `Gopkg.toml` and `Gopkg.lock` files
233 |
234 | Some daily `dep` commands:
235 |
236 | ```bash
237 | # Installs all dependencies listed in "Gopkg.toml" and "Gopkg.lock"
238 | dep ensure
239 |
240 | # Ensures that "errors" & "bar" packages will be installed
241 | dep ensure -add github.com/pkg/errors github.com/foo/bar
242 |
243 | # Ensures that "bar" package will be updated
244 | dep ensure -update github.com/foo/bar
245 |
246 | # Reports if project and dependencies are out of sync
247 | dep check
248 | ```
249 |
250 | For more info on `dep` check out
251 | [Dep Docs](https://golang.github.io/dep/docs/introduction.html)
252 |
253 | ### Go modules
254 |
255 | Go modules are a new addition to in Go `1.11` where developers are
256 | allowed to write Go code outside `$GOPATH`. This is not an article about
257 | Go modules but the idea is simple, there is a configuration file `go.mod`
258 | which tells Go how to resolve dependencies for a specific package.
259 |
260 | Also a separate tool `go mod` is available for that purpose.
261 |
262 | For more info check out
263 |
264 | [Go Modules](https://github.com/golang/go/wiki/Modules#go-111-modules)
265 |
266 | [Go Modules in 2019](https://blog.golang.org/modules2019)
267 |
268 | ### Notes:
269 |
270 | Usually artifacts inside `bin` and `pkg` are generated and no
271 | developer interaction is required. Basically all developers care about
272 | is `$GOPATH/src` where the source code lives.
273 |
274 | ### For more info check out:
275 |
276 | [How to write Go code](https://golang.org/doc/code.html)
277 |
278 | [GOPATH](https://github.com/golang/go/wiki/GOPATH)
279 |
280 | [Dep](https://golang.github.io/dep/docs/introduction.html)
281 |
282 | [Go Modules](https://github.com/golang/go/wiki/Modules#go-111-modules)
283 |
284 | Back to
285 | [Go Basics](https://github.com/gophertuts/go-basics)
286 |
--------------------------------------------------------------------------------
/gophertuts.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
116 |
--------------------------------------------------------------------------------
/internal-directory/Internal directory.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/internal-directory/Internal directory.key
--------------------------------------------------------------------------------
/internal-directory/README.md:
--------------------------------------------------------------------------------
1 | # `internal` directory in Go
2 |
3 |
4 | ## Medium version 📖
5 |
6 | [Go module proxy](https://medium.com/@gophertuts/packages-in-go-df5438123548)
7 |
8 | ### More info
9 |
10 | ```bash
11 | go help importpath
12 |
13 | go help goproxy
14 | ```
15 |
16 | ## Resources 💎
17 |
18 | - [Go 1.5 vendor experiment](https://go.googlesource.com/proposal/+/master/design/25719-go15vendor.md)
19 | - [Vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories)
20 | - [VGO module](https://research.swtch.com/vgo-module)
21 | - [Athens project](https://docs.gomods.io)
22 | - [Athens project - GitHub](https://github.com/gomods/athens)
23 | - [Athens docker image](https://docs.gomods.io)
24 | - [Go project structure](https://vsupalov.com/go-folder-structure/)
25 | - [Go project layout](https://github.com/golang-standards/project-layout)
26 |
27 | ## FEEDBACK ⚗
28 |
29 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
30 |
31 | ## COMMUNITY 🙌
32 |
33 | [GopherTuts Discord](https://discord.gg/4sgecdh)
34 |
35 | ---
36 |
37 | Back to
38 | [Go Basics](https://github.com/gophertuts/go-basics)
39 |
40 |
41 |
--------------------------------------------------------------------------------
/number-systems/Number systems.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/number-systems/Number systems.key
--------------------------------------------------------------------------------
/number-systems/Number systems.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/number-systems/Number systems.pdf
--------------------------------------------------------------------------------
/number-systems/Number systems.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/number-systems/Number systems.pptx
--------------------------------------------------------------------------------
/number-systems/README.md:
--------------------------------------------------------------------------------
1 | # Number systems
2 |
3 | ## Overall topics discussed in this tutorial
4 |
5 | - Base 2
6 | - Base 10
7 | - Base 16
8 | - Conversion from base 10 to N
9 | - Conversion from base N to 10
10 |
11 | ## Resources 💎
12 |
13 | - [Program memory allocation types](https://wiki.osdev.org/Program_Memory_Allocation_Types)
14 | - [Calling convention](https://wiki.osdev.org/Calling_Convention)
15 | - [Memory layout in C](https://www.geeksforgeeks.org/memory-layout-of-c-program/)
16 | - [Zero page](https://en.wikipedia.org/wiki/Zero_page)
17 | - [Go playground exercise](https://play.golang.org/p/RzAfXqZ6XiY)
18 |
19 | ## FEEDBACK ⚗
20 |
21 | [GopherTuts TypeForm](https://gophertuts.typeform.com/to/j2CJmC)
22 |
23 | ## COMMUNITY 🙌
24 |
25 | [GopherTuts Discord](https://discord.gg/4sgecdh)
26 |
27 | ---
28 |
29 | Back to
30 | [Go Basics](https://github.com/gophertuts/go-basics)
31 |
32 |
33 |
--------------------------------------------------------------------------------
/package-management/Package management.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/package-management/Package management.key
--------------------------------------------------------------------------------
/package-management/README.md:
--------------------------------------------------------------------------------
1 | # Package management in Go
2 |
3 | ## Resources 💎
4 |
5 | - [Migrating to Go modules](https://blog.golang.org/migrating-to-go-modules)
6 |
7 | ## FEEDBACK ⚗
8 |
9 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
10 |
11 | ## COMMUNITY 🙌
12 |
13 | [GopherTuts Discord](https://discord.gg/4sgecdh)
14 |
15 | ---
16 |
17 | Back to
18 | [Go Basics](https://github.com/gophertuts/go-basics)
19 |
20 |
21 |
--------------------------------------------------------------------------------
/package-management/basic-http/Gopkg.lock:
--------------------------------------------------------------------------------
1 | # This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'.
2 |
3 |
4 | [[projects]]
5 | digest = "1:abeb38ade3f32a92943e5be54f55ed6d6e3b6602761d74b4aab4c9dd45c18abd"
6 | name = "github.com/fsnotify/fsnotify"
7 | packages = ["."]
8 | pruneopts = "UT"
9 | revision = "c2828203cd70a50dcccfb2761f8b1f8ceef9a8e9"
10 | version = "v1.4.7"
11 |
12 | [[projects]]
13 | digest = "1:c0d19ab64b32ce9fe5cf4ddceba78d5bc9807f0016db6b1183599da3dcc24d10"
14 | name = "github.com/hashicorp/hcl"
15 | packages = [
16 | ".",
17 | "hcl/ast",
18 | "hcl/parser",
19 | "hcl/printer",
20 | "hcl/scanner",
21 | "hcl/strconv",
22 | "hcl/token",
23 | "json/parser",
24 | "json/scanner",
25 | "json/token",
26 | ]
27 | pruneopts = "UT"
28 | revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241"
29 | version = "v1.0.0"
30 |
31 | [[projects]]
32 | digest = "1:84a35669b4b31cc20ffc89c3b2ab32f2189fb2366a973efa1c25e009ef6ae1c6"
33 | name = "github.com/julienschmidt/httprouter"
34 | packages = ["."]
35 | pruneopts = "UT"
36 | revision = "4eec211fa4e8df74ed978dc5681612131854144f"
37 | version = "v1.3.0"
38 |
39 | [[projects]]
40 | digest = "1:5a0ef768465592efca0412f7e838cdc0826712f8447e70e6ccc52eb441e9ab13"
41 | name = "github.com/magiconair/properties"
42 | packages = ["."]
43 | pruneopts = "UT"
44 | revision = "de8848e004dd33dc07a2947b3d76f618a7fc7ef1"
45 | version = "v1.8.1"
46 |
47 | [[projects]]
48 | digest = "1:53bc4cd4914cd7cd52139990d5170d6dc99067ae31c56530621b18b35fc30318"
49 | name = "github.com/mitchellh/mapstructure"
50 | packages = ["."]
51 | pruneopts = "UT"
52 | revision = "3536a929edddb9a5b34bd6861dc4a9647cb459fe"
53 | version = "v1.1.2"
54 |
55 | [[projects]]
56 | digest = "1:bbd3997f0121200f72b64d7a3826eb8a0b910d6a4c19894c9fe2852b9e5eaf3b"
57 | name = "github.com/pelletier/go-toml"
58 | packages = ["."]
59 | pruneopts = "UT"
60 | revision = "8fe62057ea2d46ce44254c98e84e810044dbe197"
61 | version = "v1.5.0"
62 |
63 | [[projects]]
64 | digest = "1:bb495ec276ab82d3dd08504bbc0594a65de8c3b22c6f2aaa92d05b73fbf3a82e"
65 | name = "github.com/spf13/afero"
66 | packages = [
67 | ".",
68 | "mem",
69 | ]
70 | pruneopts = "UT"
71 | revision = "588a75ec4f32903aa5e39a2619ba6a4631e28424"
72 | version = "v1.2.2"
73 |
74 | [[projects]]
75 | digest = "1:08d65904057412fc0270fc4812a1c90c594186819243160dc779a402d4b6d0bc"
76 | name = "github.com/spf13/cast"
77 | packages = ["."]
78 | pruneopts = "UT"
79 | revision = "8c9545af88b134710ab1cd196795e7f2388358d7"
80 | version = "v1.3.0"
81 |
82 | [[projects]]
83 | digest = "1:1b753ec16506f5864d26a28b43703c58831255059644351bbcb019b843950900"
84 | name = "github.com/spf13/jwalterweatherman"
85 | packages = ["."]
86 | pruneopts = "UT"
87 | revision = "94f6ae3ed3bceceafa716478c5fbf8d29ca601a1"
88 | version = "v1.1.0"
89 |
90 | [[projects]]
91 | digest = "1:524b71991fc7d9246cc7dc2d9e0886ccb97648091c63e30eef619e6862c955dd"
92 | name = "github.com/spf13/pflag"
93 | packages = ["."]
94 | pruneopts = "UT"
95 | revision = "2e9d26c8c37aae03e3f9d4e90b7116f5accb7cab"
96 | version = "v1.0.5"
97 |
98 | [[projects]]
99 | digest = "1:11118bd196646c6515fea3d6c43f66162833c6ae4939bfb229b9956d91c6cf17"
100 | name = "github.com/spf13/viper"
101 | packages = ["."]
102 | pruneopts = "UT"
103 | revision = "b5bf975e5823809fb22c7644d008757f78a4259e"
104 | version = "v1.4.0"
105 |
106 | [[projects]]
107 | digest = "1:a5158647b553c61877aa9ae74f4015000294e47981e6b8b07525edcbb0747c81"
108 | name = "go.uber.org/atomic"
109 | packages = ["."]
110 | pruneopts = "UT"
111 | revision = "df976f2515e274675050de7b3f42545de80594fd"
112 | version = "v1.4.0"
113 |
114 | [[projects]]
115 | digest = "1:ed14edb4b5ec8eff801b1e8217ffaf021729c5a1dee9d940af5bb3302ab7297d"
116 | name = "go.uber.org/multierr"
117 | packages = ["."]
118 | pruneopts = "UT"
119 | revision = "71e610a0e48dbda460d9c18adca8b5f2de04a7c1"
120 | version = "v1.2.0"
121 |
122 | [[projects]]
123 | digest = "1:676160e6a4722b08e0e26b11521d575c2cb2b6f0c679e1ee6178c5d8dee51e5e"
124 | name = "go.uber.org/zap"
125 | packages = [
126 | ".",
127 | "buffer",
128 | "internal/bufferpool",
129 | "internal/color",
130 | "internal/exit",
131 | "zapcore",
132 | ]
133 | pruneopts = "UT"
134 | revision = "27376062155ad36be76b0f12cf1572a221d3a48c"
135 | version = "v1.10.0"
136 |
137 | [[projects]]
138 | branch = "master"
139 | digest = "1:7c927f17d868be652a4cfe7de23e4292dea5b14d974a1d536e3b7cb7e79fd695"
140 | name = "golang.org/x/sys"
141 | packages = ["unix"]
142 | pruneopts = "UT"
143 | revision = "06d7bd2c5f4f4a6cc6e910b611851044253bd7d1"
144 |
145 | [[projects]]
146 | digest = "1:1093f2eb4b344996604f7d8b29a16c5b22ab9e1b25652140d3fede39f640d5cd"
147 | name = "golang.org/x/text"
148 | packages = [
149 | "internal/gen",
150 | "internal/triegen",
151 | "internal/ucd",
152 | "transform",
153 | "unicode/cldr",
154 | "unicode/norm",
155 | ]
156 | pruneopts = "UT"
157 | revision = "342b2e1fbaa52c93f31447ad2c6abc048c63e475"
158 | version = "v0.3.2"
159 |
160 | [[projects]]
161 | digest = "1:59f10c1537d2199d9115d946927fe31165959a95190849c82ff11e05803528b0"
162 | name = "gopkg.in/yaml.v2"
163 | packages = ["."]
164 | pruneopts = "UT"
165 | revision = "f221b8435cfb71e54062f6c6e99e9ade30b124d5"
166 | version = "v2.2.4"
167 |
168 | [solve-meta]
169 | analyzer-name = "dep"
170 | analyzer-version = 1
171 | input-imports = [
172 | "github.com/julienschmidt/httprouter",
173 | "github.com/spf13/viper",
174 | "go.uber.org/zap",
175 | ]
176 | solver-name = "gps-cdcl"
177 | solver-version = 1
178 |
--------------------------------------------------------------------------------
/package-management/basic-http/Gopkg.toml:
--------------------------------------------------------------------------------
1 | # Gopkg.toml example
2 | #
3 | # Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
4 | # for detailed Gopkg.toml documentation.
5 | #
6 | # required = ["github.com/user/thing/cmd/thing"]
7 | # ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
8 | #
9 | # [[constraint]]
10 | # name = "github.com/user/project"
11 | # version = "1.0.0"
12 | #
13 | # [[constraint]]
14 | # name = "github.com/user/project2"
15 | # branch = "dev"
16 | # source = "github.com/myfork/project2"
17 | #
18 | # [[override]]
19 | # name = "github.com/x/y"
20 | # version = "2.4.0"
21 | #
22 | # [prune]
23 | # non-go = false
24 | # go-tests = true
25 | # unused-packages = true
26 |
27 |
28 | [prune]
29 | go-tests = true
30 | unused-packages = true
31 |
32 | [[constraint]]
33 | name = "github.com/julienschmidt/httprouter"
34 | version = "1.3.0"
35 |
36 | [[constraint]]
37 | name = "go.uber.org/zap"
38 | version = "1.10.0"
39 |
40 | [[constraint]]
41 | name = "github.com/spf13/viper"
42 | version = "1.4.0"
43 |
--------------------------------------------------------------------------------
/package-management/basic-http/app/app.go:
--------------------------------------------------------------------------------
1 | package app
2 |
3 | import (
4 | "context"
5 | "log"
6 | "net/http"
7 | "os"
8 | "os/signal"
9 | "time"
10 |
11 | "github.com/julienschmidt/httprouter"
12 | "go.uber.org/zap"
13 |
14 | "github.com/gophertuts/go-basics/package-management/basic-http/config"
15 | "github.com/gophertuts/go-basics/package-management/basic-http/controllers"
16 | "github.com/gophertuts/go-basics/package-management/basic-http/logging"
17 | )
18 |
19 | type App struct {
20 | Config config.Manager
21 | Router *httprouter.Router
22 | Server http.Server
23 | }
24 |
25 | func New() *App {
26 | err := logging.InitLogger()
27 | if err != nil {
28 | log.Fatal(err)
29 | }
30 | manager, err := config.New()
31 | if err != nil {
32 | logging.Logger.Error("could not initialize config")
33 | }
34 | router := controllers.New()
35 | return &App{
36 | Config: manager,
37 | Router: router,
38 | }
39 | }
40 |
41 | func (app *App) Start() error {
42 | logging.Logger.Info(
43 | "application started",
44 | zap.String("listen", app.Config.Listen()),
45 | )
46 | server := http.Server{
47 | Addr: app.Config.Listen(),
48 | Handler: app.Router,
49 | }
50 | app.Server = server
51 | err := server.ListenAndServe()
52 | if err == http.ErrServerClosed {
53 | logging.Logger.Info("http server is closed")
54 | return nil
55 | }
56 | return err
57 | }
58 |
59 | func (app *App) Shutdown() {
60 | // Need to call Sync() before exiting. See Sync docs
61 | defer logging.Logger.Sync()
62 | ch := make(chan struct{})
63 | go func() {
64 | logging.Logger.Info("shutting down http server")
65 | if err := app.Server.Shutdown(context.Background()); err != nil {
66 | logging.Logger.Error("error on server shutdown", zap.Error(err))
67 | }
68 | close(ch)
69 | }()
70 | select {
71 | case <-ch:
72 | logging.Logger.Info("application was shut down")
73 | case <-time.After(2 * time.Second):
74 | logging.Logger.Error("could not shut down in", zap.Duration("timeout", 2 * time.Second))
75 | }
76 | }
77 |
78 | type Shutdowner interface {
79 | Shutdown()
80 | }
81 |
82 | func ListenForSignals(signals []os.Signal, servers ...Shutdowner) {
83 | c := make(chan os.Signal, 1)
84 | signal.Notify(c, signals...)
85 | sig := <-c
86 | logging.Logger.Info("received shutdown signal", zap.String("signal", sig.String()))
87 |
88 | for _, server := range servers {
89 | server.Shutdown()
90 | }
91 | os.Exit(0)
92 | }
93 |
--------------------------------------------------------------------------------
/package-management/basic-http/config/config.go:
--------------------------------------------------------------------------------
1 | package config
2 |
3 | import "github.com/spf13/viper"
4 |
5 | const (
6 | listen = "listen"
7 | )
8 |
9 | type Manager struct{}
10 |
11 | func New() (Manager, error) {
12 | viper.SetConfigFile("config/config.yaml")
13 | viper.SetConfigType("yaml")
14 | if err := viper.ReadInConfig(); err != nil {
15 | return Manager{}, err
16 | }
17 | return Manager{}, nil
18 | }
19 |
20 | func (m Manager) Listen() string {
21 | return viper.GetString(listen)
22 | }
23 |
--------------------------------------------------------------------------------
/package-management/basic-http/config/config.yaml:
--------------------------------------------------------------------------------
1 | listen: "0.0.0.0:8080"
2 |
--------------------------------------------------------------------------------
/package-management/basic-http/controllers/index.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 |
8 | "github.com/julienschmidt/httprouter"
9 | )
10 |
11 | func index(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
12 | _, err := fmt.Fprint(w, "Welcome to index!\n")
13 | if err != nil {
14 | log.Fatal(err)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/package-management/basic-http/controllers/people.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 |
8 | "github.com/julienschmidt/httprouter"
9 | )
10 |
11 | func people(w http.ResponseWriter, _ *http.Request, ps httprouter.Params) {
12 | _, err := fmt.Fprintf(w, "Hello Mr. %s!\n", ps.ByName(nameParam))
13 | if err != nil {
14 | log.Fatal(err)
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/package-management/basic-http/controllers/routes.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | import (
4 | "github.com/julienschmidt/httprouter"
5 | )
6 |
7 | const (
8 | nameParam = "name"
9 | )
10 |
11 | func New() *httprouter.Router {
12 | router := httprouter.New()
13 | router.GET("/", index)
14 | router.GET("/people/:name", people)
15 | return router
16 | }
17 |
--------------------------------------------------------------------------------
/package-management/basic-http/logging/logger.go:
--------------------------------------------------------------------------------
1 | package logging
2 |
3 | import (
4 | "go.uber.org/zap"
5 | )
6 |
7 | var Logger *zap.Logger
8 |
9 | func InitLogger() error {
10 | logger, err := zap.NewProduction()
11 | defer logger.Sync()
12 | if err != nil {
13 | return err
14 | }
15 | Logger = logger
16 | return nil
17 | }
18 |
--------------------------------------------------------------------------------
/package-management/basic-http/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "log"
5 | "os"
6 | "syscall"
7 |
8 | "github.com/gophertuts/go-basics/package-management/basic-http/app"
9 | )
10 |
11 | func main() {
12 | application := app.New()
13 | go func() {
14 | err := application.Start()
15 | if err != nil {
16 | log.Fatal(err)
17 | }
18 | }()
19 | app.ListenForSignals([]os.Signal{syscall.SIGINT, syscall.SIGTERM}, application)
20 | }
21 |
--------------------------------------------------------------------------------
/package-management/cmd-directory/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/custom-library/internal/pkg.go:
--------------------------------------------------------------------------------
1 | package internal
2 |
--------------------------------------------------------------------------------
/package-management/custom-library/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/dep/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/glide/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/go-mod/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/internal-directory/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/package-archives/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/private-packages/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/semver/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/package-management/vendor-directory/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
--------------------------------------------------------------------------------
/packages/Packages.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/packages/Packages.key
--------------------------------------------------------------------------------
/packages/Packages.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/packages/Packages.pdf
--------------------------------------------------------------------------------
/packages/Packages.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/packages/Packages.pptx
--------------------------------------------------------------------------------
/packages/README.md:
--------------------------------------------------------------------------------
1 | # Packages in Go
2 |
3 | #### Package types
4 |
5 | ```bash
6 | # Displays useful information about import paths
7 | go help importpath
8 |
9 | # cd into package types
10 | cd $GOPATH/src/github.com/gophertuts/go-basics/packages/package-types
11 |
12 | # run the main func inside the main package
13 | go run main.go
14 |
15 | # attempt to run non main package services
16 | # THIS WILL NOT WORK (non main package)
17 | go run services/s1.go
18 | ```
19 |
20 | #### Helpful information on Packages
21 |
22 | ```bash
23 | go help modules
24 | ```
25 |
26 | # Medium version 📖
27 |
28 | [Packages in Go](https://medium.com/@gophertuts/packages-in-go-df5438123548)
29 |
30 | ## Resources 💎
31 |
32 | - [Go packages](https://www.callicoder.com/golang-packages/)
33 | - [Naming](https://talks.golang.org/2014/names.slide#1)
34 | - [Package names](https://blog.golang.org/package-names)
35 | - [Code review comments](https://github.com/golang/go/wiki/CodeReviewComments)
36 | - [Migrating to Go modules](https://blog.golang.org/migrating-to-go-modules)
37 | - [Go project structure](https://vsupalov.com/go-folder-structure/)
38 | - [Go project layout](https://github.com/golang-standards/project-layout)
39 | - [Go project layout - Medium](https://medium.com/golang-learn/go-project-layout-e5213cdcfaa2)
40 | - [Best practices for industrial programming](https://youtu.be/PTE4VJIdHPg)
41 |
42 | ## FEEDBACK ⚗
43 |
44 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
45 |
46 | ## COMMUNITY 🙌
47 |
48 | [GopherTuts Discord](https://discord.gg/4sgecdh)
49 |
50 | ---
51 |
52 | Back to
53 | [Go Basics](https://github.com/gophertuts/go-basics)
54 |
55 |
56 |
--------------------------------------------------------------------------------
/packages/cross-reference/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | _ "github.com/gophertuts/go-basics/packages/cross-reference/p1"
7 | )
8 |
9 | func main() {
10 | fmt.Println("This will not print")
11 | }
12 |
--------------------------------------------------------------------------------
/packages/cross-reference/p1/p1.go:
--------------------------------------------------------------------------------
1 | package p1
2 |
3 | import _ "github.com/gophertuts/go-basics/packages/cross-reference/p2"
4 |
--------------------------------------------------------------------------------
/packages/cross-reference/p2/p2.go:
--------------------------------------------------------------------------------
1 | package p2
2 |
3 | import _ "github.com/gophertuts/go-basics/packages/cross-reference/p1"
4 |
--------------------------------------------------------------------------------
/packages/exported-vs-unexported/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/gophertuts/go-basics/packages/exported-vs-unexported/pkg"
7 | )
8 |
9 | func main() {
10 | //fmt.Println(pkg.unExported)
11 | fmt.Println(pkg.Exported)
12 | fmt.Println(pkg.Public())
13 | //fmt.Println(pkg.private())
14 | }
15 |
--------------------------------------------------------------------------------
/packages/exported-vs-unexported/pkg/pkg.go:
--------------------------------------------------------------------------------
1 | package pkg
2 |
3 | const (
4 | unExported = 15
5 | Exported = 10
6 | )
7 |
8 | func private() string {
9 | return "some public string"
10 | }
11 |
12 | func Public() string {
13 | return "some public string"
14 | }
15 |
--------------------------------------------------------------------------------
/packages/go-get/README.md:
--------------------------------------------------------------------------------
1 | # `go get`
2 |
3 | ```bash
4 | # Downloads all referenced dependencies (packages)
5 | # by every package in current directory
6 | go get ./...
7 |
8 | # Downloads latest version (master) of 'pkg'
9 | # with module aware feature on
10 | go get pkg
11 |
12 | # Downloads v1.0.0 of 'pkg' package
13 | go get pkg@v1.0.0
14 |
15 | # Downloads 'pkg' package at git commit hash
16 | go get pkg@af044c0995fe
17 |
18 | # Locks the revision number for this package
19 | # to prevent future breaking changes
20 | go get github.com/lestrrat/go-jwx@b7d4802
21 | cat go.mod
22 |
23 | # Downloads or updates 'pkg' package
24 | go get -u pkg
25 |
26 | # For more info on go get
27 | go help get
28 | ```
29 |
30 | ### Module aware feature
31 |
32 | In order to turn this feature on you need
33 | to export `GO111MODULE=on` env variable
34 | inside your shell profile
35 |
36 | # `go clean`
37 |
38 | ```bash
39 | # cleans binaries generated with `go build`
40 | # Note: it does not clean the binaries
41 | # generated using `go build -o binary-name`
42 | go clean
43 |
44 | # For more info on go get
45 | go help clean
46 | ```
47 |
48 | ### Best practices
49 |
50 | - Use `go get ./...` when fetching all dependencies for
51 | a project
52 | - Use `go get pkg` for fetching the latest version
53 | of a package
54 | - Use `go get pkg@v1.0.0` for fetching a specific non
55 | breaking version of the package
56 | Note: `GO111MODULE=on` ENV var should be set to be able
57 | to use module aware feature
58 |
--------------------------------------------------------------------------------
/packages/go-get/go.mod:
--------------------------------------------------------------------------------
1 | module github.com/gophertuts/go-basics/packages/go-get
2 |
3 | go 1.12
4 |
5 | require github.com/julienschmidt/httprouter v1.3.0
6 |
--------------------------------------------------------------------------------
/packages/go-get/go.sum:
--------------------------------------------------------------------------------
1 | github.com/julienschmidt/httprouter v1.2.0 h1:TDTW5Yz1mjftljbcKqRcrYhd4XeOoI98t+9HbQbYf7g=
2 | github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
3 | github.com/julienschmidt/httprouter v1.3.0 h1:U0609e9tgbseu3rBINet9P48AI/D3oJs4dN7jwJOQ1U=
4 | github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
5 |
--------------------------------------------------------------------------------
/packages/go-get/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | "log"
6 | "net/http"
7 |
8 | "github.com/julienschmidt/httprouter"
9 | )
10 |
11 | func main() {
12 | router := httprouter.New()
13 | router.GET("/", func(w http.ResponseWriter, req *http.Request, _ httprouter.Params) {
14 | // handle errors bastard
15 | _, _ = fmt.Fprintf(w, "Welcome!")
16 | })
17 | router.GET("/people/:name", func(w http.ResponseWriter, req *http.Request, ps httprouter.Params) {
18 | name := ps.ByName("name")
19 | // handle errors bastard
20 | _, _ = fmt.Fprintf(w, "Welcome %s", name)
21 | })
22 | log.Fatal(http.ListenAndServe(":8080", router))
23 | }
24 |
--------------------------------------------------------------------------------
/packages/locals-vs-globals/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | var (
6 | number = 10.0
7 | delta = .33333
8 | )
9 |
10 | func main() {
11 | fmt.Println(squareDelta(number))
12 | }
13 |
--------------------------------------------------------------------------------
/packages/locals-vs-globals/square.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "fmt"
4 |
5 | func squareDelta(x float64) float64 {
6 | fmt.Println("squaring with delta", delta)
7 | return x * x * delta
8 | }
9 |
--------------------------------------------------------------------------------
/packages/multiple-packages/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 | //"github.com/gophertuts/go-basics/packages/multiple-packages"
6 | )
7 |
8 | func main() {
9 | // USING
10 | // go build
11 | // go run *.go
12 | fmt.Println("This will not work")
13 | }
14 |
--------------------------------------------------------------------------------
/packages/multiple-packages/pkgA.go:
--------------------------------------------------------------------------------
1 | package pkgA
2 |
--------------------------------------------------------------------------------
/packages/multiple-packages/pkgB.go:
--------------------------------------------------------------------------------
1 | package pkgB
2 |
--------------------------------------------------------------------------------
/packages/package-naming/anotherWeirdPkg/another-weird.go:
--------------------------------------------------------------------------------
1 | package anotherWeirdPkg
2 |
3 | func W() {
4 | }
5 |
--------------------------------------------------------------------------------
/packages/package-naming/collision/collision.go:
--------------------------------------------------------------------------------
1 | package collision
2 |
3 | func New() {
4 | }
5 |
--------------------------------------------------------------------------------
/packages/package-naming/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "github.com/gophertuts/go-basics/packages/package-naming/anotherWeirdPkg"
5 | "github.com/gophertuts/go-basics/packages/package-naming/collision"
6 | "github.com/gophertuts/go-basics/packages/package-naming/redundant"
7 | "github.com/gophertuts/go-basics/packages/package-naming/right"
8 | "github.com/gophertuts/go-basics/packages/package-naming/weird_long_package_name_with_underscores"
9 | )
10 |
11 | func main() {
12 | // GOOD
13 | redundant.NewMemory()
14 | // BAD
15 | // no need for the word 'Redundant', you already reference the package redundant
16 | redundant.NewRedundantMemory()
17 |
18 | // BAD
19 | weird_long_package_name_with_underscores.F()
20 | anotherWeirdPkg.W()
21 |
22 | // BAD - package and directory names are different
23 | // Don't be afraid of collision as long as the package is different
24 | wrong.New()
25 | collision.New()
26 | }
27 |
--------------------------------------------------------------------------------
/packages/package-naming/redundant/redundant.go:
--------------------------------------------------------------------------------
1 | package redundant
2 |
3 | func NewMemory() {
4 | }
5 |
6 | func NewRedundantMemory() {
7 | }
8 |
--------------------------------------------------------------------------------
/packages/package-naming/right/wrong.go:
--------------------------------------------------------------------------------
1 | package wrong
2 |
3 | func New() {
4 | }
5 |
--------------------------------------------------------------------------------
/packages/package-naming/weird_long_package_name_with_underscores/weird.go:
--------------------------------------------------------------------------------
1 | package weird_long_package_name_with_underscores
2 |
3 | func F() {
4 | }
5 |
--------------------------------------------------------------------------------
/packages/package-organization/controllers/c1.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | // THIS IS JUST A PLACEHOLDER
4 |
--------------------------------------------------------------------------------
/packages/package-organization/controllers/c1_test.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | // THIS IS JUST A PLACEHOLDER TEST FILE
4 |
--------------------------------------------------------------------------------
/packages/package-organization/controllers/c2.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | // THIS IS JUST A PLACEHOLDER
4 |
--------------------------------------------------------------------------------
/packages/package-organization/controllers/c2_test.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | // THIS IS JUST A PLACEHOLDER TEST FILE
4 |
--------------------------------------------------------------------------------
/packages/package-organization/controllers/controllers.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | // THIS IS JUST A PLACEHOLDER
4 |
--------------------------------------------------------------------------------
/packages/package-organization/controllers/controllers_test.go:
--------------------------------------------------------------------------------
1 | package controllers
2 |
3 | // THIS IS JUST A PLACEHOLDER TEST FILE
4 |
--------------------------------------------------------------------------------
/packages/package-organization/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | // THIS IS JUST A PLACEHOLDER
4 |
--------------------------------------------------------------------------------
/packages/package-types/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import "github.com/gophertuts/go-basics/packages/package-types/services"
4 |
5 | func main() {
6 | services.NewS1()
7 | }
8 |
--------------------------------------------------------------------------------
/packages/package-types/services/s1.go:
--------------------------------------------------------------------------------
1 | package services
2 |
3 | import "fmt"
4 |
5 | func NewS1() {
6 | fmt.Println("creating new S1 service")
7 | }
8 |
--------------------------------------------------------------------------------
/packages/test-packages/pkg1/pkg1.go:
--------------------------------------------------------------------------------
1 | package pkg1
2 |
3 | import "github.com/gophertuts/go-basics/packages/test-packages/pkg2"
4 |
5 | const Exported = pkg2.Exported
6 |
--------------------------------------------------------------------------------
/packages/test-packages/pkg1/pkg1_test.go:
--------------------------------------------------------------------------------
1 | package pkg1
2 |
3 | import "github.com/gophertuts/go-basics/packages/test-packages/pkg2"
4 |
5 | const Exported2 = pkg2.Exported2
6 |
--------------------------------------------------------------------------------
/packages/test-packages/pkg2/pkg2.go:
--------------------------------------------------------------------------------
1 | package pkg2
2 |
3 | const Exported = 10
4 |
--------------------------------------------------------------------------------
/packages/test-packages/pkg2/pkg2_test.go:
--------------------------------------------------------------------------------
1 | package pkg2
2 |
3 | const Exported2 = 10
4 |
--------------------------------------------------------------------------------
/vendor-directory/README.md:
--------------------------------------------------------------------------------
1 | # `vendor` directory in Go
2 |
3 | ## Overview
4 |
5 | In this section we'll be talking about the `vendor` directory feature
6 | in Go.
7 |
8 | Since `Go 1.5`, the Go team decided to make our life's easier and allowed the
9 | community to develop package managers, so we all enjoy downloading
10 | and installing specific locked versions of software, without
11 | breaking our precious applications.
12 |
13 | By the end of this tutorial you will perfectly know what the `vendor`
14 | directory is in Go and how to make use of it.
15 |
16 | ## Medium version 📖
17 |
18 | [Vendor directory in Go](https://medium.com/@gophertuts/vendor-directory-in-go-723de6cab46a)
19 |
20 | ### More info
21 |
22 | ```bash
23 | go help importpath
24 |
25 | go help goproxy
26 | ```
27 |
28 | ## Resources 💎
29 |
30 | - [Go 1.5 vendor experiment](https://go.googlesource.com/proposal/+/master/design/25719-go15vendor.md)
31 | - [Vendor directories](https://golang.org/cmd/go/#hdr-Vendor_Directories)
32 | - [Import path checking](https://golang.org/cmd/go/#hdr-Import_path_checking)
33 | - [Go Modules](https://blog.golang.org/using-go-modules)
34 | - [VGO module](https://research.swtch.com/vgo-module)
35 | - [Athens project](https://docs.gomods.io)
36 | - [Athens project - GitHub](https://github.com/gomods/athens)
37 | - [Athens docker image](https://docs.gomods.io)
38 | - [Go project structure](https://vsupalov.com/go-folder-structure/)
39 | - [Go project layout](https://github.com/golang-standards/project-layout)
40 |
41 | ## FEEDBACK ⚗
42 |
43 | [GopherTuts TypeForm](http://feedback.gophertuts.com)
44 |
45 | ## COMMUNITY 🙌
46 |
47 | [GopherTuts Discord](https://discord.gg/4sgecdh)
48 |
49 | ---
50 |
51 | Back to
52 | [Go Basics](https://github.com/gophertuts/go-basics)
53 |
54 |
55 |
--------------------------------------------------------------------------------
/vendor-directory/Vendor directory.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/vendor-directory/Vendor directory.key
--------------------------------------------------------------------------------
/vendor-directory/Vendor directory.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/vendor-directory/Vendor directory.pdf
--------------------------------------------------------------------------------
/vendor-directory/Vendor directory.pptx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gophertuts/go-basics/e34dbd4ff13f19903156cd8231df30e98c1999ab/vendor-directory/Vendor directory.pptx
--------------------------------------------------------------------------------
/vendor-directory/main.go:
--------------------------------------------------------------------------------
1 | package main
2 |
3 | import (
4 | "fmt"
5 |
6 | "github.com/julienschmidt/httprouter"
7 |
8 | _ "github.com/gophertuts/go-basics/vendor-directory/pkg1"
9 | _ "github.com/gophertuts/go-basics/vendor-directory/pkg2"
10 | _ "github.com/gophertuts/go-basics/vendor-directory/pkg3"
11 | )
12 |
13 | func main() {
14 | fmt.Println("some packages imported")
15 | router := httprouter.New()
16 | fmt.Println("router is just a number:", router)
17 | }
18 |
--------------------------------------------------------------------------------
/vendor-directory/pkg1/pkg1.go:
--------------------------------------------------------------------------------
1 | package pkg1
2 |
3 | import "fmt"
4 |
5 | func init() {
6 | fmt.Println("importing pkg1 from $GOPATH")
7 | }
8 |
--------------------------------------------------------------------------------
/vendor-directory/pkg2/pkg2.go:
--------------------------------------------------------------------------------
1 | package pkg2
2 |
3 | import "fmt"
4 |
5 | func init() {
6 | fmt.Println("importing pkg2 from $GOPATH")
7 | }
8 |
--------------------------------------------------------------------------------
/vendor-directory/pkg3/pkg3.go:
--------------------------------------------------------------------------------
1 | package pkg3
2 |
3 | import "fmt"
4 |
5 | func init() {
6 | fmt.Println("importing pkg3 from $GOPATH")
7 | }
8 |
--------------------------------------------------------------------------------
/vendor-directory/vendor/github.com/gophertuts/go-basics/vendor-directory/pkg3/pkg3.go:
--------------------------------------------------------------------------------
1 | package pkg3
2 |
3 | import "fmt"
4 |
5 | func init() {
6 | fmt.Println("importing pkg3 from vendor")
7 | }
8 |
--------------------------------------------------------------------------------
/vendor-directory/vendor/github.com/julienschmidt/httprouter/router.go:
--------------------------------------------------------------------------------
1 | package httprouter
2 |
3 | func New() int {
4 | return 10
5 | }
6 |
--------------------------------------------------------------------------------