{"id":19704530,"url":"https://github.com/luckylittle/go-playground","last_synced_at":"2025-07-01T04:33:30.245Z","repository":{"id":109045469,"uuid":"139007548","full_name":"luckylittle/go-playground","owner":"luckylittle","description":"Go playground \u0026 notes","archived":false,"fork":false,"pushed_at":"2022-10-12T06:59:38.000Z","size":1019,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-27T17:22:13.977Z","etag":null,"topics":["go","go-lang","go-notes","go-packages","golang"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/luckylittle.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"luckylittle","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"lfx_crowdfunding":null,"custom":null}},"created_at":"2018-06-28T11:11:29.000Z","updated_at":"2022-10-12T06:59:43.000Z","dependencies_parsed_at":null,"dependency_job_id":"a0ef0f0d-9341-43f3-8a00-68d6c3898ed8","html_url":"https://github.com/luckylittle/go-playground","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/luckylittle/go-playground","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckylittle%2Fgo-playground","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckylittle%2Fgo-playground/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckylittle%2Fgo-playground/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckylittle%2Fgo-playground/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/luckylittle","download_url":"https://codeload.github.com/luckylittle/go-playground/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/luckylittle%2Fgo-playground/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":262897563,"owners_count":23381443,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","go-lang","go-notes","go-packages","golang"],"created_at":"2024-11-11T21:23:10.047Z","updated_at":"2025-07-01T04:33:30.221Z","avatar_url":"https://github.com/luckylittle.png","language":"Go","funding_links":["https://github.com/sponsors/luckylittle"],"categories":[],"sub_categories":[],"readme":"# GO LANG\n\n##### ...or go home :-)\n\n---\n\n## Introduction\n\n### $GOPATH\n\n* Defaults to your home directory like so `~/go/`.\n\n* It’s easiest to think of the $GOPATH as being a workspace that contains all of your projects and dependencies.\n\n* As long as all your go code lives inside it you are going to have an easier me working with go.\n\n* You should set it yourself, so you can control the location and eventually share among multiple users:\n\n1. Configure `$GOPATH`, e.g. `mkdir -p ~/Projects/go/{bin,pkg,src};mkdir -p ~/Projects/go/src/github.com/luckylittle;echo export 'GOPATH=/home/lmaly/Projects/go' \u003e\u003e ~/.zshrc`.\n2. Check the Go environment variables with `go env`.\n\n* If you look in the $GOPATH directory you will see three directories, `bin`, `pkg` and `src`. The `bin` directory is where installed binaries that have a main package are placed when you run `go install`. If you install a project without a main package it is moved into the `pkg` directory. Lastly `src` which is where you should do all your development work.\n\n* It is good idea to `PATH=$PATH:$(go env GOPATH)/bin`\n\n### Dependencies\n\n* When you use the command `go get github.com/user/repo/` what happens is that a copy of the github repository is cloned into your `$GOPATH/src/github/user/repo/` directory. `go get` works with other source control systems as well so you are not limited to git.\n\n* Inside the root of your go project dependencies are checked to exist inside the vendor directory before looking at `$GOPATH`. As such if you place your dependencies in there they will be the ones your code builds and links against. To move them into the location is thankfully simple. Install `dep` then run `dep ensure` which will inspect your code and move what is required into `vendor`. Check the `dep` docs for details on how to update/remove dependencies. Keep in mind that `dep` will place a `Gopkg.lock` and `Gopkg.toml` file in the root path for tracking these.\n\n[Go dep](https://github.com/golang/dep)\n\n### Building\n\n1. Write Hello World in `main.go` in `$GOPATH/src/github.com/luckylittle/hello/main.go`.\n2. `go build` and `./hello` inside `$GOPATH/src/github.com/luckylittle/hello/`, cleanup with `go clean`.\n    or `go run main.go` which does not build `./hello` so you don't need to do `go clean`.\n\nSo, if you have main package:\n\n```bash\ngo build   # builds the command and leaves the result in the current working directory.\ngo install # builds the command in a temporary directory then moves it to $GOPATH/bin.\n```\n\nFor packages:\n\n```bash\ngo build   # builds your package then discards the results.\ngo install # builds then installs the package in your $GOPATH/pkg directory.\n```\n\nIf you want to cross compile, that is build on Linux for Windows or vice versa you can set what architecture your want to target and the OS through environment variables. You can view your defaults in go env but to change them you would do something like:\n\n```bash\nGOOS=darwin GOARCH=amd64 go build\nGOOS=windows GOARCH=amd64 go build\nGOOS=linux GOARCH=amd64 go build\n```\n\nOS Specific source code:\n\n```\nmain_darwin.go\nmain_linux.go\nmain_windows.go\n```\n\n* Multi-stage Docker build example:\n\n```Dockerfile\nFROM golang:1.10\nCOPY . /go/src/github.com/luckylittle/hello\nWORKDIR /go/src/github.com/luckylittle/hello\nRUN CGO_ENABLED=0 go build main.go\n\nFROM alpine:3.7\nRUN apk add --no-cache ca-certificates\nCOPY --from=0 /go/src/github.com/luckylittle/hello .\nCMD [\"./main\"]\n```\n\n### Testing\n\n* To create a test file you need only create a file with `_test` as a suffix in the name. For example to create a file test you may call the file `file_test.go`.\n\n* To run all the tests:\n\n```bash\ngo test ./...\n```\n\n## Static \u0026 Dynamic Types\n\n```go\naddition = x + y\n\nx = 1\ny = \"three\"\n```\n\nStatically typed = !error!\nDynamically typed = \"1three\"\n\n### Declaring types in Go\n\n#### Integer\n\n`var i int = 3`\n\nNote: Signed int, which means positive \u0026 negative numbers are supported.\n\n#### Float\n\n`var f float64 = 0.111`\n\n#### String\n\n`var s string = \"foo\"`\n\n#### Arrays\n\n* Length and type must be specified\n\n`var beatles [4]string`\n\nNote: Starts with `0`.\n\n### Check the type of variable\n\n```go\nimport (\n    \"reflect\"\n)\nfunction main () {\n    ...\n        fmt.Println(reflect.TypeOf(s))\n        ...\n}\n```\n\n### Converting between types\n\n* For converting from/to strings, use `strconv` package from Standard Library (SL)\n\n1. String -\u003e Boolean:\n\n```go\n    var s string = \"true\"\n    b, err := strconv.ParseBool(s)\n```\n\n2. Boolean -\u003e String:\n\n```go\n    s := strconv.FormatBool(true)\n    fmt.Println(s)\n```\n\n## Variables\n\n* The type of variable is important\n\n* After a variable is declared with a type, it is NOT possible to declare it again\n\n* Re-assigning the value is allowed\n\n### Shorthand declaration\n\n`var s, t string = \"foo\", \"bar\"`\n`s := \"Hello World\" // Only inside functions!`\n\n### Zero values\n\n```go\nfunc main() {\n    var i int       // i = 0\n    var f float64   // f = 0\n    var b bool      // b = false\n    var s string    // s = \"\"\n}\n```\n\n* Checking if the zero value has been assigned?\n\n```go\n    func main() {\n        var s string    // s = \"\"\n        if s == \"\" {\n            fmt.Printf(\"s has not been assigned a value and is zero valued\")\n        }\n    }\n```\n\n### Variable scope\n\n* Lexically scoped using blocks = meaning Go defines where variables can or cannot be referenced.\n\n* A block is defined as a possible empty sequence of declarations and statements within matching brace brackets = `{` \u0026 `}`.\n\n* A variable declared within those brackets may be accessed anywhere within this block.\n\n* Brackets within brackets denote a new, `inner` block.\n\n* `Inner` blocks can access vars within `outer` blocks.\n\n* `Outer` blocks CANNOT access vars within `inner` blocks.\n\n### Pointers\n\n* Allocated position in computer's memory = `\u0026variable`\n\n* Prevent two instances of the variable in different memory locations\n\n* By using asterisk, the value is printed = `*variable`\n\n```go\nfunc main() {\n    s := \"Hello world\"\n    fmt.Println(\u0026s) // 0xc42000e1e0\n}\n```\n\n### Constants\n\n* Values do not change during the life of a program\n\n`const greeting string = \"Hello, world\"`\n\n## Functions\n\n* Function signature:\n\n```go\nfunc addUp(x int, y int) int { // expected variables in the brackets (), after closing bracket comes the return value\n    return x + y               // if the func signature declares a return value, the func body must end in a terminating statement\n}                              // terminated function body\n```\n\n### Returning multiple values\n\n```go\nfunc getPrize() (int, string) {\n    i := 2\n    s := \"goldfish:\n    return i, s\n}\n\nfunc main () {\n    quantity, prize := getPrize()\n    fmt.Printf(\"You won %v %v\\n\", quantity, prize)\n}\n```\n\n### Variadic func\n\n* Accept variable number of arguments using 3 dots (`...`)\n\n```go\nfunc sumNumbers(numbers...int) int {\n    ...\n}\n```\n\n### Named return values\n\n* Assign values to named variables befre they are returned\n\n* The func signature declares the variables as part of the return values\n\n```go\nfunc sayHi() (x, y string) {\n    x = \"hello\"\n    y = \"world\"\n    return                      // naked return statement, works if you use named return values. Returns the named variables in the same order.\n}\n```\n\n### Recursive functions\n\n* Can call themselves indefinitely or until particular condition is met\n\n* Calls itself as the result value of a terminating statement\n\n### Passing functions as values\n\n* It is possible to assign functions to a value and call them at a later date\n\n* Functions are type in Go so they can be passed to another function\n\n```go\nfunc main () {\n    fn := func() {\n        fmt.Println(\"function called\")\n    }\n    fn() // function is called\n}\n```\n\nPassing func as an argument:\n\n```go\n/* recursive function */\npackage main\n\nimport \"fmt\"\n\nfunc anotherFunction(f func() string) string {  // sub function signature shows funct argument that returns string, receiving function also returns string\n    return f()\n}\n\nfunc main() {\n    fn := func() string {\n        return \"function called\"\n    }\n    fmt.Println(anotherFunction(fn))\n}\n```\n\n## Control flow\n\n### if\n\n* Multiple `if` statements can be run one after another and they will be evaluated in the order they are in the source code.\n\n```go\nfunc main () {\n    b := true\n    if b {                              // evaluates whether b is true\n        fmt.Println(\"b is true!\")       // code is executed, because b is true\n    }\n}\n```\n\n### else\n\n* If nothing else is true, run this.\n\n```go\nfunc main () {\n    b := false\n    if b {\n        fmt.Println(\"b is true!\")\n    } else {\n        fmt.Println(\"b is false!\")\n    }\n}\n```\n\n### else if\n\n```go\nfunc main() {\n    i := 2\n    if i == 3 {\n        fmt.Println(\"i is 3\")\n    } else if i == 2 {\n        fmt.Println(\"i is 2\")\n    }\n}\n```\n\n### Comparison, arithmetic operators, logical operators\n\n* Must be the same type\n\n* `==`, `!=`, `\u003c`, `\u003c=`, `\u003e`, `\u003e=`\n\n* `+`, `-`, `*`, `/`, `%`\n\n* `\u0026\u0026`, `||`, `!`\n\n### switch\n\n```go\nfunc main() {\n    i := 2\n    switch i {\n        case 2:                     // if an expression is found to be true, code is evaluated\n            fmt.Println(\"Two\")\n        case 3:\n            fmt.Println(\"Three\")\n        case 4:\n            fmt.Println(\"Four\")\n        default:                    // if none of the case statements is true\n            fmt.Println(\"I don't know\")\n    }\n}\n```\n\n### for\n\n```go\nfunc main() {\n    i := 0\n    for i \u003c 10 {                  // if this is true, the code is executed\n        i++                       // incremented by one\n        fmt.Println(\"i is\", i)\n    }                             // when i is no longer less than 10, no longer executed and loop stops\n}\n```\n\n## For with init \u0026 post\n\n* `init` = this is run only once before the first iteration\n\n* `post` = this is evaluated after each iteration\n\n```go\nfunc main() {\n    for i := 0;i \u003c10;i++ {\n        fmt.Println(\"i is\", i)\n    }\n}\n```\n\n### For with range\n\n* Can loop over data structure\n\n* Iteration starts at `0`\n\n```go\nfunc main() {\n    numbers := []int{1,2,3,4}                        // slice containing four integers\n    for i, n := range numbers {                      // iteration variable = i, value = n\n        fmt.Println(\"The index of the loop is\", i)\n        fmt.Println(\"The value from the array is\", n)\n    }\n}\n```\n\n### defer\n\n* Allows a func to be executed after surrounding func returns.\n\n* Usually cleanup operations.\n\n* If multiple `defer`s are present, they will be executed in reverse order that they were declared in the source code.\n\n```go\nfunc main(){\n    defer fmt.Println(\"I am run after the function completes\")      // last\n    fmt.Println(\"Hello World!\")                                     // first\n}\n```\n\n---\n\n[@luckylittle](https://github.com/luckylittle)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluckylittle%2Fgo-playground","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluckylittle%2Fgo-playground","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluckylittle%2Fgo-playground/lists"}