{"id":15933996,"url":"https://github.com/arthurgousset/go","last_synced_at":"2026-01-18T16:31:42.698Z","repository":{"id":254182673,"uuid":"845730225","full_name":"arthurgousset/go","owner":"arthurgousset","description":"✨ Go cheat sheet","archived":false,"fork":false,"pushed_at":"2024-09-14T22:02:45.000Z","size":35,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-09T03:43:40.959Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/arthurgousset.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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}},"created_at":"2024-08-21T20:19:29.000Z","updated_at":"2024-09-14T22:02:49.000Z","dependencies_parsed_at":"2024-08-24T10:22:51.039Z","dependency_job_id":"6232f388-009a-4775-b43c-48885b3c3dcd","html_url":"https://github.com/arthurgousset/go","commit_stats":null,"previous_names":["arthurgousset/go"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurgousset%2Fgo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurgousset%2Fgo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurgousset%2Fgo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/arthurgousset%2Fgo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/arthurgousset","download_url":"https://codeload.github.com/arthurgousset/go/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247024153,"owners_count":20870940,"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":[],"created_at":"2024-10-07T03:00:38.319Z","updated_at":"2026-01-18T16:31:42.685Z","avatar_url":"https://github.com/arthurgousset.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go (Cheat Sheet)\n\n\u003e [!TIP]  \n\u003e Most of the concepts and text below are taken from the Go track on\n\u003e [exercism.org](https://exercism.org/tracks/go). The material is licensed under a MIT license,\n\u003e which is included in this repository as well.\n\nOther resources:\n\n1. [yourbasic.org](https://yourbasic.org/) by [prof. Stefan Nilsson](https://yourbasic.org/about/)\n   \u003e Code should be correct, clear and efficient. Prefer simple. Avoid clever.\n\n## Installation\n\nOfficial instructions: [go.dev/doc/install](https://go.dev/doc/install).\n\nInstead of using the official instructions, I used `brew` to install Go on my Mac.\n\n```sh\n$ brew install golang\n```\n\n## Basics (from [exercism.org](https://exercism.org/tracks/go/concepts/basics))\n\n### Introduction\n\n[Go](https://golang.org) is a statically typed, compiled programming language. This exercise\nintroduces three major language features: Packages, Functions, and Variables.\n\n### Packages\n\nGo applications are organized in packages. A package is a collection of source files located in the\nsame directory. All source files in a directory must share the same package name. When a package is\nimported, only entities (functions, types, variables, constants) whose names start with a capital\nletter can be used / accessed. The recommended style of naming in Go is that identifiers will be\nnamed using `camelCase`, except for those meant to be accessible across packages which should be\n`PascalCase`.\n\n```go\npackage lasagna\n```\n\n### Variables\n\nGo is statically-typed, which means all variables\n[must have a defined type](https://en.wikipedia.org/wiki/Type_system) at compile-time.\n\nVariables can be defined by explicitly specifying a type:\n\n```go\nvar explicit int // Explicitly typed\n```\n\nYou can also use an initializer, and the compiler will assign the variable type to match the type of\nthe initializer.\n\n```go\nimplicit := 10   // Implicitly typed as an int\n```\n\nOnce declared, variables can be assigned values using the `=` operator. Once declared, a variable's\ntype can never change.\n\n```go\ncount := 1 // Assign initial value\ncount = 2  // Update to new value\n\ncount = false // This throws a compiler error due to assigning a non `int` type\n```\n\n### Constants\n\nConstants hold a piece of data just like variables, but their value cannot change during the\nexecution of the program.\n\nConstants are defined using the `const` keyword and can be numbers, characters, strings or booleans:\n\n```go\nconst Age = 21 // Defines a numeric constant 'Age' with the value of 21\n```\n\n## Functions (from [exercism.org](https://exercism.org/tracks/go/concepts/functions))\n\nA function allows you to group code into a reusable unit. It consists of the `func` keyword, the\nname of the function, and a comma-separated list of zero or more parameters and types in round\nbrackets.\n\n```go\npackage greeting\n\n// Hello is a public function.\nfunc Hello (name string) string {\n    return hi(name)\n}\n\n// hi is a private function.\nfunc hi (name string) string {\n    return \"hi \" + name\n}\n```\n\n#x## Function Parameters\n\nAll parameters must be explicitly typed; there is no type inference for parameters. There are no\ndefault values for parameters so all function parameters are required.\n\n```go\nimport \"fmt\"\n\n// No parameters\nfunc PrintHello() {\n    fmt.Println(\"Hello\")\n}\n\n// Two parameters\nfunc PrintGreetingName(greeting string, name string) {\n  fmt.Println(greeting + \" \" + name)\n}\n```\n\nParameters of the same type can be declared together, followed by a single type declaration.\n\n```go\nimport \"fmt\"\n\nfunc PrintGreetingName(greeting, name string) {\n  fmt.Println(greeting + \" \" + name)\n}\n```\n\n### Parameters vs. Arguments\n\nLet's quickly cover two terms that are often confused together: `parameters` and `arguments`.\nFunction parameters are the names defined in the function's signature, such as `greeting` and `name`\nin the function `PrintGreetingName` above. Function arguments are the concrete values passed to the\nfunction parameters when we invoke the function. For instance, in the example below, `\"Hello\"` and\n`\"Katrina\"` are the arguments passed to the `greeting` and `name` parameters:\n\n```go\nPrintGreetingName(\"Hello\", \"Katrina\")\n```\n\n### Return Values\n\nThe function parameters are followed by zero or more return values which must also be explicitly\ntyped. Single return values are left bare, multiple return values are wrapped in parenthesis. Values\nare returned to the calling code from functions using the `return` keyword. There can be multiple\n`return` statements in a function. The execution of the function ends as soon as it hits one of\nthose `return` statements. If multiple values are to be returned from a function, they are comma\nseparated.\n\n```go\nfunc Hello(name string) string {\n  return \"Hello \" + name\n}\n\nfunc HelloAndGoodbye(name string) (string, string) {\n  return \"Hello \" + name, \"Goodbye \" + name\n}\n```\n\n### Invoking Functions\n\nInvoking a function is done by specifying the function name and passing arguments for each of the\nfunction's parameters in parenthesis.\n\n```go\nimport \"fmt\"\n\n// No parameters, no return value\nfunc PrintHello() {\n    fmt.Println(\"Hello\")\n}\n// Called like this:\nPrintHello()\n\n// One parameter, one return value\nfunc Hello(name string) string {\n  return \"Hello \" + name\n}\n// Called like this:\ngreeting := Hello(\"Dave\")\n\n// Multiple parameters, multiple return values\nfunc SumAndMultiply(a, b int) (int, int) {\n    return a+b, a*b\n}\n// Called like this:\naplusb, atimesb := SumAndMultiply(a, b)\n```\n\n### Named Return Values and Naked Return\n\nAs well as parameters, return values can optionally be named. If named return values are used, a\n`return` statement without arguments will return those values. This is known as a 'naked' return.\n\n```go\nfunc SumAndMultiplyThenMinus(a, b, c int) (sum, mult int) {\n    sum, mult = a+b, a*b\n    sum -= c\n    mult -= c\n    return\n}\n```\n\n### Pass by Value vs. Pass by Reference\n\nIt is also important to clarify the concept of passing by value and passing by reference.\n\nFirst, let's clarify passing by value. In the example below, when we pass the variable `val` to the\nfunction `MultiplyByTwo`, we passed a copy of `val`. Because of this, `newVal` has the updated value\n`4` but the original variable `val` is still `2`. Behind the scene, Go essentially makes a copy of\nthe original value so that only this copy, a.k.a. `v`, is modified by the function.\n\n```go\nval := 2\nfunc MultiplyByTwo(v int) int {\n    v = v * 2\n    return v\n}\nnewVal := MultiplyByTwo(val)\n// newval is 4, val is still 2 because only a copy of its value was passed into the function\n```\n\nStrictly speaking, all arguments are passed by value in Go, i.e. a copy is made of the value or data\nprovided to the function. But if you don't want to make a copy of the data that is passed to a\nfunction and want to change the data in the function, then you should use `pointers` as arguments,\na.k.a. pass by reference.\n\n### Pointers\n\nWe use a `pointer` to achieve passing by reference. By passing `pointer` arguments into a function,\nwe could modify the underlying data passed into the function instead of only operating on a copy of\nthe data.\n\nFor now, it is sufficient to know that pointer types can be recognized by the `*` in front of the\ntype in the function signature.\n\n```go\nfunc HandlePointers(x, y *int) {\n    // Some logic to handle integer values referenced by pointers x and y\n}\n```\n\nIf the concept of `pointer` is confusing, no worries. We have a dedicated section later in the\nsyllabus to help you master pointers.\n\n### Exceptions\n\nNote that `slices` and `maps` are exceptions to the above-mentioned rule. When we pass a `slice` or\na `map` as arguments into a function, they are treated as pointer types even though there is no\nexplicit `*` in the type. This means that if we pass a slice or map into a function and modify its\nunderlying data, the changes will be reflected on the original slice or map.\n\n## Comments (from [exercism.org](https://exercism.org/tracks/go/exercises/weather-forecast))\n\nIn the previous exercise, we saw that there are two ways to write comments in Go: single-line\ncomments that are preceded by `//`, and multiline comment blocks that are wrapped with `/*` and\n`*/`.\n\n### Documentation comments\n\nIn Go, comments play an important role in documenting code. They are used by the `godoc` command,\nwhich extracts these comments to create documentation about Go packages. A documentation comment\nshould be a complete sentence that starts with the name of the thing being described and ends with a\nperiod.\n\nComments should precede packages as well as exported identifiers, for example exported functions,\nmethods, package variables, constants, and structs, which you will learn more about in the next\nexercises.\n\nA package-level variable can look like this:\n\n```go\n// TemperatureCelsius represents a certain temperature in degrees Celsius.\nvar TemperatureCelsius float64\n```\n\n### Package comments\n\nPackage comments should be written directly before a package clause (`package x`) and begin with\n`Package x ...` like this:\n\n```go\n// Package kelvin provides tools to convert\n// temperatures to and from Kelvin.\npackage kelvin\n```\n\n### Function comments\n\nA function comment should be written directly before the function declaration. It should be a full\nsentence that starts with the function name. For example, an exported comment for the function\n`Calculate` should take the form `Calculate ...`. It should also explain what arguments the function\ntakes, what it does with them, and what its return values mean, ending in a period):\n\n```go\n// CelsiusFreezingTemp returns an integer value equal to the temperature at which water freezes in degrees Celsius.\nfunc CelsiusFreezingTemp() int {\n\treturn 0\n}\n```\n\n## Numbers (from [exercism.org](https://exercism.org/tracks/go/concepts/numbers))\n\nGo contains basic numeric types that can represent sets of either integer or floating-point values.\nThere are different types depending on the size of value you require and the architecture of the\ncomputer where the application is running (e.g. 32-bit and 64-bit).\n\nFor the sake of this exercise you will only be dealing with:\n\n- `int`: e.g. `0`, `255`, `2147483647`. A signed integer that is at least 32 bits in size (value\n  range of: -2147483648 through 2147483647). But this will depend on the systems architecture. Most\n  modern computers are 64 bit, therefore `int` will be 64 bits in size (value rate of:\n  -9223372036854775808 through 9223372036854775807).\n\n- `float64`: e.g. `0.0`, `3.14`. Contains the set of all 64-bit floating-point numbers.\n\n- `uint`: e.g. `0`, `255`. An unsigned integer that is the same size as `int` (value range of: 0\n  through 4294967295 for 32 bits and 0 through 18446744073709551615 for 64 bits)\n\nNumbers can be converted to other numeric types through Type Conversion.\n\n## Floating-point numbers (from [exercism.org](https://exercism.org/tracks/go/concepts/floating-point-numbers))\n\nA floating-point number is a number with zero or more digits behind the decimal separator. Examples\nare `-2.4`, `0.1`, `3.14`, `16.984025` and `1024.0`.\n\nDifferent floating-point types can store different numbers of digits after the digit separator -\nthis is referred to as its precision.\n\nGo has two floating-point types:\n\n- `float32`: 32 bits (~6-9 digits precision).\n- `float64`: 64 bits (~15-17 digits precision). This is the default floating-point type.\n\nAs can be seen, both types can store a different number of digits. This means that trying to store\nPI in a `float32` will only store the first 6 to 9 digits (with the last digit being rounded).\n\nBy default, Go will use `float64` for floating-point numbers, unless the floating-point number is:\n\n1. assigned to a variable with type `float32`, or\n2. returned from a function with return type `float32`, or\n3. passed as an argument to the `float32()` function.\n\nThe `math` package contains many helpful mathematical functions.\n\n## Arithmetic Operators (from [exercism.org](https://exercism.org/tracks/go/concepts/arithmetic-operators))\n\nGo supports many standard arithmetic operators:\n\n| Operator | Example        |\n| -------- | -------------- |\n| `+`      | `4 + 6 == 10`  |\n| `-`      | `15 - 10 == 5` |\n| `*`      | `2 * 3 == 6`   |\n| `/`      | `13 / 3 == 4`  |\n| `%`      | `13 % 3 == 1`  |\n\nFor integer division, the remainder is dropped (e.g. `5 / 2 == 2`).\n\nGo has shorthand assignment for the operators above (e.g. `a += 5` is short for `a = a + 5`). Go\nalso supports the increment and decrement statements `++` and `--` (e.g. `a++`).\n\n### Converting between types\n\nConverting between types is done via a function with the name of the type to convert to. For\nexample:\n\n```go\nvar x int = 42 // x has type int\nf := float64(x) // f has type float64 (ie. 42.0)\nvar y float64 = 11.9 // y has type float64\ni := int(y) // i has type int (ie. 11)\n```\n\n### Arithmetic operations on different types\n\nIn many languages you can perform arithmetic operations on different types of variables, but in Go\nthis gives an error. For example:\n\n```go\nvar x int = 42\n\n// this line produces an error\nvalue := float32(2.0) * x // invalid operation: mismatched types float32 and int\n\n// you must convert int type to float32 before performing arithmetic operation\nvalue := float32(2.0) * float32(x)\n```\n\n## Booleans (from [exercism.org](https://exercism.org/tracks/go/concepts/booleans))\n\nBooleans in Go are represented by the predeclared boolean type `bool`, which values can be either\n`true` or `false`. It's a defined type.\n\n```go\nvar closed bool    // boolean variable 'closed' implicitly initialized with 'false'\nspeeding := true   // boolean variable 'speeding' initialized with 'true'\nhasError := false  // boolean variable 'hasError' initialized with 'false'\n```\n\nGo supports three logical operators that can evaluate expressions down to Boolean values, returning\neither `true` or `false`.\n\n| Operator    | What it means                                 |\n| ----------- | --------------------------------------------- |\n| `\u0026\u0026` (and)  | It is true if both statements are true.       |\n| `\\|\\|` (or) | It is true if at least one statement is true. |\n| `!` (not)   | It is true only if the statement is false.    |\n\n## Strings (from [exercism.org](https://exercism.org/tracks/go/concepts/strings))\n\nA `string` in Go is an immutable sequence of bytes, which don't necessarily have to represent\ncharacters.\n\nA string literal is defined between double quotes:\n\n```go\nconst name = \"Jane\"\n```\n\nStrings can be concatenated via the `+` operator:\n\n```go\n\"Jane\" + \" \" + \"Austen\"\n// =\u003e \"Jane Austen\"\n```\n\nSome special characters need to be escaped with a leading backslash, such as `\\t` for a tab and `\\n`\nfor a new line in strings.\n\n```go\n\"How is the weather today?\\nIt's sunny\"\n// =\u003e\n// How is the weather today?\n// It's sunny\n```\n\nThe `strings` package contains many useful functions to work on strings. For more information about\nstring functions, check out the [strings package documentation](https://pkg.go.dev/strings). Here\nare some examples:\n\n```go\nimport \"strings\"\n\n// strings.ToLower returns the string given as argument with all its characters lowercased\nstrings.ToLower(\"MaKEmeLoweRCase\")\n// =\u003e \"makemelowercase\"\n\n// strings.Repeat returns a string with a substring given as argument repeated many times\nstrings.Repeat(\"Go\", 3)\n// =\u003e \"GoGoGo\"\n```\n\n## Comparison (from [exercism.org](https://exercism.org/tracks/go/concepts/comparison))\n\nIn Go numbers can be compared using the following relational and equality operators.\n\n| Comparison       | Operator |\n| ---------------- | -------- |\n| equal            | `==`     |\n| not equal        | `!=`     |\n| less             | `\u003c`      |\n| less or equal    | `\u003c=`     |\n| greater          | `\u003e`      |\n| greater or equal | `\u003e=`     |\n\nThe result of the comparison is always a boolean value, so either `true` or `false`.\n\n```go\na := 3\n\na != 4 // true\na \u003e 5  // false\n```\n\nThe comparison operators above can also be used to compare strings. In that case a lexicographical\n(dictionary) order is applied. For example:\n\n```Go\n\t\"apple\" \u003c \"banana\"  // true\n\t\"apple\" \u003e \"banana\"  // false\n```\n\n## Conditionals If (from [exercism.org](https://exercism.org/tracks/go/concepts/conditionals-if))\n\nConditionals in Go are similar to conditionals in other languages. The underlying type of any\nconditional operation is the `bool` type, which can have the value of `true` or `false`.\nConditionals are often used as flow control mechanisms to check for various conditions.\n\nFor checking a particular case an `if` statement can be used, which executes its code if the\nunderlying condition is `true` like this:\n\n```go\nvar value string\n\nif value == \"val\" {\n    return \"was val\"\n}\n```\n\nIn scenarios involving more than one case many `if` statements can be chained together using the\n`else if` and `else` statements.\n\n```go\nvar number int\nresult := \"This number is \"\n\nif number \u003e 0 {\n    result += \"positive\"\n} else if number \u003c 0 {\n    result += \"negative\"\n} else {\n    result += \"zero\"\n}\n```\n\nIf statements can also include a short initialization statement that can be used to initialize one\nor more variables for the if statement. For example:\n\n```go\nnum := 7\nif v := 2 * num; v \u003e 10 {\n    fmt.Println(v)\n} else {\n    fmt.Println(num)\n}\n// Output: 14\n```\n\n\u003e Note: any variables created in the initialization statement go out of scope after the end of the\n\u003e if statement.\n\n## Packages (from [exercism.org](https://exercism.org/tracks/go/concepts/packages))\n\nIn Go an application is organized in packages. A package is a collection of source files located in\nthe same folder. All source files in a folder must have the same package name at the top of the\nfile. By convention packages are named to be the same as the folder they are located in.\n\n```go\npackage greeting\n```\n\nGo provides an extensive standard library of packages which you can use in your program using the\n`import` keyword. Standard library packages are imported using their name.\n\n```go\npackage greeting\n\nimport \"fmt\"\n```\n\nAn imported package is then addressed with the package name:\n\n```go\nworld := \"World\"\nfmt.Sprintf(\"Hello %s\", world)\n```\n\nGo determines if an item can be called by code in other packages through how it is declared. To make\na function, type, variable, constant or struct field externally visible (known as _exported_) the\nname must start with a capital letter.\n\n```go\npackage greeting\n\n// Hello is a public function (callable from other packages).\nfunc Hello(name string) string {\n    return \"Hello \" + name\n}\n\n// hello is a private function (not callable from other packages).\nfunc hello(name string) string {\n    return \"Hello \" + name\n}\n```\n\n## String Formatting (from [exercism.org](https://exercism.org/tracks/go/concepts/string-formatting))\n\nGo provides an in-built package called `fmt` (format package) which offers a variety of functions to\nmanipulate the format of input and output. The most commonly used function is `Sprintf`, which uses\nverbs like `%s` to interpolate values into a string and returns that string.\n\n```go\nimport \"fmt\"\n\nfood := \"taco\"\nfmt.Sprintf(\"Bring me a %s\", food)\n// Returns: Bring me a taco\n```\n\nIn Go floating point values are conveniently formatted with Sprintf's verbs: `%g` (compact\nrepresentation), `%e` (exponent) or `%f` (non exponent). All three verbs allow the field's width and\nnumeric position to be controlled.\n\n```go\nimport \"fmt\"\n\nnumber := 4.3242\nfmt.Sprintf(\"%.2f\", number)\n// Returns: 4.32\n```\n\nYou can find a full list of available verbs in the [format package documentation][fmt-docs].\n\n`fmt` contains other functions for working with strings, such as `Println` which simply prints the\narguments it receives to the console and `Printf` which formats the input in the same way as\n`Sprintf` before printing it.\n\n[fmt-docs]: https://pkg.go.dev/fmt\n\n### Format 'verbs'\n\nSource: [pkg.go.dev/fmt](https://pkg.go.dev/fmt)\n\nGeneral:\n\n```\n%v\tthe value in a default format\n\twhen printing structs, the plus flag (%+v) adds field names\n%#v\ta Go-syntax representation of the value\n\t(floating-point infinities and NaNs print as ±Inf and NaN)\n%T\ta Go-syntax representation of the type of the value\n%%\ta literal percent sign; consumes no value\n```\n\nBoolean:\n\n```\n%t\tthe word true or false\n```\n\nInteger:\n\n```\n%b\tbase 2\n%c\tthe character represented by the corresponding Unicode code point\n%d\tbase 10\n%o\tbase 8\n%O\tbase 8 with 0o prefix\n%q\ta single-quoted character literal safely escaped with Go syntax.\n%x\tbase 16, with lower-case letters for a-f\n%X\tbase 16, with upper-case letters for A-F\n%U\tUnicode format: U+1234; same as \"U+%04X\"\n```\n\nFloating-point and complex constituents:\n\n```\n%b\tdecimalless scientific notation with exponent a power of two,\n\tin the manner of strconv.FormatFloat with the 'b' format,\n\te.g. -123456p-78\n%e\tscientific notation, e.g. -1.234456e+78\n%E\tscientific notation, e.g. -1.234456E+78\n%f\tdecimal point but no exponent, e.g. 123.456\n%F\tsynonym for %f\n%g\t%e for large exponents, %f otherwise. Precision is discussed below.\n%G\t%E for large exponents, %F otherwise\n%x\thexadecimal notation (with decimal power of two exponent), e.g. -0x1.23abcp+20\n%X\tupper-case hexadecimal notation, e.g. -0X1.23ABCP+20\n```\n\nString and slice of bytes (treated equivalently with these verbs):\n\n```\n%s\tthe uninterpreted bytes of the string or slice\n%q\ta double-quoted string safely escaped with Go syntax\n%x\tbase 16, lower-case, two characters per byte\n%X\tbase 16, upper-case, two characters per byte\n```\n\nSlice:\n\n```\n%p\taddress of 0th element in base 16 notation, with leading 0x\n```\n\nPointer:\n\n```\n%p\tbase 16 notation, with leading 0x\nThe %b, %d, %o, %x and %X verbs also work with pointers,\nformatting the value exactly as if it were an integer.\n```\n\nThe default format for %v is:\n\n```\nbool:                    %t\nint, int8 etc.:          %d\nuint, uint8 etc.:        %d, %#x if printed with %#v\nfloat32, complex64, etc: %g\nstring:                  %s\nchan:                    %p\npointer:                 %p\n```\n\nFor compound objects, the elements are printed using these rules, recursively, laid out like this:\n\n```\nstruct:             {field0 field1 ...}\narray, slice:       \\[elem0 elem1 ...\\]\nmaps:               map\\[key1:value1 key2:value2 ...\\]\npointer to above:   \u0026{}, \u0026\\[\\], \u0026map\\[\\]\n```\n\nWidth is specified by an optional decimal number immediately preceding the verb. If absent, the\nwidth is whatever is necessary to represent the value. Precision is specified after the (optional)\nwidth by a period followed by a decimal number. If no period is present, a default precision is\nused. A period with no following number specifies a precision of zero. Examples:\n\n```\n%f     default width, default precision\n%9f    width 9, default precision\n%.2f   default width, precision 2\n%9.2f  width 9, precision 2\n%9.f   width 9, precision 0\n```\n\nWidth and precision are measured in units of Unicode code points, that is, runes. (This differs from\nC's printf where the units are always measured in bytes.) Either or both of the flags may be\nreplaced with the character '\\*', causing their values to be obtained from the next operand\n(preceding the one to format), which must be of type int.\n\nOther flags:\n\n```\n'+'\talways print a sign for numeric values;\n\tguarantee ASCII-only output for %q (%+q)\n'-'\tpad with spaces on the right rather than the left (left-justify the field)\n'#'\talternate format: add leading 0b for binary (%#b), 0 for octal (%#o),\n\t0x or 0X for hex (%#x or %#X); suppress 0x for %p (%#p);\n\tfor %q, print a raw (backquoted) string if \\[strconv.CanBackquote\\]\n\treturns true;\n\talways print a decimal point for %e, %E, %f, %F, %g and %G;\n\tdo not remove trailing zeros for %g and %G;\n\twrite e.g. U+0078 'x' if the character is printable for %U (%#U)\n' '\t(space) leave a space for elided sign in numbers (% d);\n\tput spaces between bytes printing strings or slices in hex (% x, % X)\n'0'\tpad with leading zeros rather than spaces;\n\tfor numbers, this moves the padding after the sign\n```\n\n## Slices (from [exercism.org](https://exercism.org/tracks/go/concepts/slices))\n\nSlices in Go are similar to lists or arrays in other languages. They hold several elements of a\nspecific type (or interface).\n\nSlices in Go are based on arrays. Arrays have a fixed size. A slice, on the other hand, is a\ndynamically-sized, flexible view of the elements of an array.\n\nA slice is written like `[]T` with `T` being the type of the elements in the slice:\n\n```go\nvar empty []int                 // an empty slice\nwithData := []int{0,1,2,3,4,5}  // a slice pre-filled with some data\n```\n\nYou can get or set an element at a given zero-based index using the square-bracket notation:\n\n```go\nwithData[1] = 5\nx := withData[1] // x is now 5\n```\n\nYou can create a new slice from an existing slice by getting a range of elements. Once again using\nsquare-bracket notation, but specifying both a starting (inclusive) and ending (exclusive) index. If\nyou don't specify a starting index, it defaults to 0. If you don't specify an ending index, it\ndefaults to the length of the slice.\n\n```go\nnewSlice := withData[2:4]\n// =\u003e []int{2,3}\nnewSlice := withData[:2]\n// =\u003e []int{0,1}\nnewSlice := withData[2:]\n// =\u003e []int{2,3,4,5}\nnewSlice := withData[:]\n// =\u003e []int{0,1,2,3,4,5}\n```\n\nYou can add elements to a slice using the `append` function. Below we append `4` and `2` to the `a`\nslice.\n\n```go\na := []int{1, 3}\na = append(a, 4, 2)\n// =\u003e []int{1,3,4,2}\n```\n\n`append` always returns a new slice, and when we just want to append elements to an existing slice,\nit's common to reassign it back to the slice variable we pass as the first argument as we did above.\n\n`append` can also be used to merge two slices:\n\n```go\nnextSlice := []int{100,101,102}\nnewSlice  := append(withData, nextSlice...)\n// =\u003e []int{0,1,2,3,4,5,100,101,102}\n```\n\n### Copy slices\n\nUse `make([]T, \u003clength\u003e)` to create a slice of type `T` and length `\u003clength\u003e`.\n\n```go\narr := []int{1, 2, 3}\ntmp := make([]int, len(arr))\ncopy(tmp, arr)\n\nfmt.Println(tmp)\n// =\u003e [1 2 3]\nfmt.Println(arr)\n// =\u003e [1 2 3]\n```\n\n\u003e The\n\u003e built-in [`copy(dst, src)`](http://golang.org/pkg/builtin/#copy) copies `min(len(dst), len(src))` elements.\n\u003e So if your `dst` is empty (`len(dst) == 0`), nothing will be copied.\n\u003e Try `tmp := make([]int, len(arr))` ([Go Playground](https://play.golang.org/p/xwISeGLzxb)):\n\nSource: [stackoverflow.com](https://stackoverflow.com/a/30182622)\n\n## Variadic Functions (from [exercism.org](https://exercism.org/tracks/go/concepts/variadic-functions))\n\nUsually, functions in Go accept only a fixed number of arguments. However, it is also possible to\nwrite variadic functions in Go.\n\nA variadic function is a function that accepts a variable number of arguments.\n\nIf the type of the last parameter in a function definition is prefixed by ellipsis `...`, then the\nfunction can accept any number of arguments for that parameter.\n\n```go\nfunc find(a int, b ...int) {\n    // ...\n}\n```\n\nIn the above function, parameter `b` is variadic and we can pass 0 or more arguments to `b`.\n\n```go\nfind(5, 6)\nfind(5, 6, 7)\nfind(5)\n```\n\n\u003e [!NOTE]  \n\u003e The variadic parameter must be the last parameter of the function.\n\nThe way variadic functions work is by converting the variable number of arguments to a slice of the\ntype of the variadic parameter.\n\nHere is an example of an implementation of a variadic function.\n\n```go\nfunc find(num int, nums ...int) {\n    fmt.Printf(\"type of nums is %T\\n\", nums)\n\n    for i, v := range nums {\n        if v == num {\n            fmt.Println(num, \"found at index\", i, \"in\", nums)\n            return\n        }\n    }\n\n    fmt.Println(num, \"not found in \", nums)\n}\n\nfunc main() {\n    find(89, 90, 91, 95)\n    // =\u003e\n    // type of nums is []int\n    // 89 not found in  [90 91 95]\n\n    find(45, 56, 67, 45, 90, 109)\n    // =\u003e\n    // type of nums is []int\n    // 45 found at index 2 in [56 67 45 90 109]\n\n    find(87)\n    // =\u003e\n    // type of nums is []int\n    // 87 not found in  []\n}\n```\n\nIn line `find(89, 90, 91, 95)` of the program above, the variable number of arguments to the find\nfunction are `90`, `91` and `95`. The `find` function expects a variadic int parameter after `num`.\nHence these three arguments will be converted by the compiler to a slice of type `int`\n`[]int{90, 91, 95}` and then it will be passed to the find function as `nums`.\n\nSometimes you already have a slice and want to pass that to a variadic function. This can be\nachieved by passing the slice followed by `...`. That will tell the compiler to use the slice as is\ninside the variadic function. The step described above where a slice is created will simply be\nomitted in this case.\n\n```go\nlist := []int{1, 2, 3}\nfind(1, list...) // \"find\" defined as shown above\n```\n\n## Conditionals Switch (from [exercism.org](https://exercism.org/tracks/go/concepts/conditionals-switch))\n\nLike other languages, Go also provides a `switch` statement. Switch statements are a shorter way to\nwrite long `if ... else if` statements. To make a switch, we start by using the keyword `switch`\nfollowed by a value or expression. We then declare each one of the conditions with the `case`\nkeyword. We can also declare a `default` case, that will run when none of the previous `case`\nconditions matched:\n\n```go\noperatingSystem := \"windows\"\n\nswitch operatingSystem {\ncase \"windows\":\n    // do something if the operating system is windows\ncase \"linux\":\n    // do something if the operating system is linux\ncase \"macos\":\n    // do something if the operating system is macos\ndefault:\n    // do something if the operating system is none of the above\n}\n```\n\nOne interesting thing about switch statements, is that the value after the `switch` keyword can be\nomitted, and we can have boolean conditions for each `case`:\n\n```go\nage := 21\n\nswitch {\ncase age \u003e 20 \u0026\u0026 age \u003c 30:\n    // do something if age is between 20 and 30\ncase age == 10:\n    // do something if age is equal to 10\ndefault:\n    // do something else for every other case\n}\n```\n\n## Structs (from [exercism.org](https://exercism.org/tracks/go/concepts/structs))\n\nIn Go, a `struct` is a sequence of named elements called _fields_, each field has a name and type.\nThe name of a field must be unique within the struct. Structs can be compared with _classes_ in the\nObject-Oriented Programming paradigm.\n\n### Defining a struct\n\nYou create a new struct by using the `type` and `struct` keywords, and explicitly define the name\nand type of the fields. For example, here we define `Shape` struct, that holds the name of a shape\nand its size:\n\n```go\ntype Shape struct {\n    name string\n    size int\n}\n```\n\nField names in structs follow the Go convention - fields whose name starts with a lower case letter\nare only visible to code in the same package, whereas those whose name starts with an upper case\nletter are visible in other packages.\n\n### Creating instances of a struct\n\nOnce you have defined the `struct`, you need to create a new instance defining the fields using\ntheir field name in any order:\n\n```go\ns := Shape {\n    name: \"Square\",\n    size: 25,\n}\n```\n\nTo read or modify instance fields, use the `.` notation:\n\n```go\n// Update the name and the size\ns.name = \"Circle\"\ns.size = 35\nfmt.Printf(\"name: %s size: %d\\n\", s.name, s.size)\n// Output: name: Circle size: 35\n```\n\nFields that don't have an initial value assigned, will have their zero value. For example:\n\n```go\ns := Shape{name: \"Circle\"}\nfmt.Printf(\"name: %s size: %d\\n\", s.name, s.size)\n// Output: name: Circle size: 0\n```\n\nYou can create an instance of a `struct` without using the field names, as long as you define the\nfields _in order_:\n\n```go\ns := Shape {\n\t\"Oval\",\n\t20,\n}\n```\n\nHowever, this syntax is considered _brittle code_ since it can break when a field is added,\nespecially when the new field is of a different type. In the following example we add an extra field\nto `Shape`:\n\n```go\ntype Shape struct {\n\tname        string\n\tdescription string // new field 'description' added\n\tsize        int\n}\n\ns := Shape{\n    \"Circle\",\n    20,\n}\n// Since the second field of the struct is now a string and not an int,\n// the compiler will throw an error when compiling the program:\n// Output: cannot use 20 (type untyped int) as type string in field value\n// Output: too few values in Shape{...}\n```\n\n### \"New\" functions\n\nSometimes it can be nice to have functions that help us create struct instances. By convention,\nthese functions are usually called `New` or have their names starting with `New`, but since they are\njust regular functions, you can give them any name you want. They might remind you of constructors\nin other languages, but in Go they are just regular functions.\n\nIn the following example, one of these `New` functions is used to create a new instance of `Shape`\nand automatically set a default value for the `size` of the shape:\n\n```go\nfunc NewShape(name string) Shape {\n\treturn Shape{\n\t\tname: name,\n\t\tsize: 100, //default-value for size is 100\n\t}\n}\n\nNewShape(\"Triangle\")\n// =\u003e Shape { name: \"Triangle\", size: 100 }\n\n```\n\nUsing `New` functions can have the following advantages:\n\n- validation of the given values\n- handling of default-values\n- since `New` functions are often declared in the same package of the structs they initialize, they\n  can initialize even private fields of the struct\n\n## For Loops (from [exercism.org](https://exercism.org/tracks/go/concepts/for-loops))\n\n### General syntax\n\nThe for loop is one of the most commonly used statements to repeatedly execute some logic. In Go it\nconsists of the `for` keyword, a header and a code block that contains the body of the loop wrapped\nin curly brackets. The header consists of 3 components separated by semicolons `;`: init, condition\nand post.\n\n```go\nfor init; condition; post {\n  // loop body - code that is executed repeatedly as long as the condition is true\n}\n```\n\n- The **init** component is some code that runs only once before the loop starts.\n- The **condition** component must be some expression that evaluates to a boolean and controls when\n  the loop should stop. The code inside the loop will run as long as this condition evaluates to\n  true. As soon as this expression evaluates to false, no more iterations of the loop will run.\n- The **post** component is some code that will run at the end of each iteration.\n\n**Note:** Unlike other languages, there are no parentheses `()` surrounding the three components of\nthe header. In fact, inserting such parenthesis is a compilation error. However, the braces `{ }`\nsurrounding the loop body are always required.\n\n### For Loops - An example\n\nThe init component usually sets up a counter variable, the condition checks whether the loop should\nbe continued or stopped and the post component usually increments the counter at the end of each\nrepetition.\n\n```go\nfor i := 1; i \u003c 10; i++ {\n  fmt.Println(i)\n}\n```\n\nThis loop will print the numbers from `1` to `9` (including `9`). Defining the step is often done\nusing an increment or decrement statement, as shown in the example above.\n\n## While loops\n\nSource: [programiz.com](https://www.programiz.com/golang/while-loop)\n\nUnlike other programming languages, Go doesn't have a dedicated keyword for a while loop. However,\nwe can use the `for` loop to perform the functionality of a while loop.\n\nSyntax of Go while loop:\n\n```go\nfor condition {\n  // code block\n}\n```\n\nHere, the loop evaluates the `condition`. If the condition is:\n\n- `true` - statements inside the loop are executed and `condition` is evaluated again\n- `false` - the loop terminates\n\n## Randomness (from [exercism.org](https://exercism.org/tracks/go/concepts/randomness))\n\nPackage [math/rand][mathrand] provides support for generating pseudo-random numbers.\n\nHere is how to generate a random integer between `0` and `99`:\n\n```go\nn := rand.Intn(100) // n is a random int, 0 \u003c= n \u003c 100\n```\n\nFunction `rand.Float64` returns a random floating point number between `0.0` and `1.0`:\n\n```go\nf := rand.Float64() // f is a random float64, 0.0 \u003c= f \u003c 1.0\n```\n\nThere is also support for shuffling a slice (or other data structures):\n\n```go\nx := []string{\"a\", \"b\", \"c\", \"d\", \"e\"}\n// shuffling the slice put its elements into a random order\nrand.Shuffle(len(x), func(i, j int) {\n\tx[i], x[j] = x[j], x[i]\n})\n```\n\n### Seeds\n\nThe number sequences generated by package `math/rand` are not truly random. Given a specific \"seed\"\nvalue, the results are entirely deterministic.\n\nIn Go 1.20+ the seed is automatically picked at random so you will see a different sequence of\nrandom numbers each time you run your program.\n\nIn prior versions of Go, the seed was `1` by default. So to get different sequences for various runs\nof the program, you had to manually seed the random number generator, e.g. with the current time,\nbefore retrieving any random numbers.\n\n```go\nrand.Seed(time.Now().UnixNano())\n```\n\n[mathrand]: https://pkg.go.dev/math/rand\n\n## Maps (for [exercism.org](https://exercism.org/tracks/go/concepts/maps))\n\nIn Go, `map` is a built-in data type that maps keys to values. In other programming languages, you\nmight be familiar with the concept of `map` as a dictionary, hash table, key/value store or an\nassociative array.\n\nSyntactically, `map` looks like this:\n\n```go\nmap[type]type\n```\n\nIt is also important to know that each key is unique, meaning that assigning the same key twice will\noverwrite the value of the corresponding key.\n\nTo create a map, you can do:\n\n```go\n  // With map literal\n  foo := map[string]int{}\n```\n\nor\n\n```go\n  // or with make function\n  foo := make(map[string]int)\n```\n\nHere are some operations that you can do with a map\n\n```go\n  // Add a value in a map with the `=` operator:\n  foo[\"bar\"] = 42\n  // Here we update the element of `bar`\n  foo[\"bar\"] = 73\n  // To retrieve a map value, you can use\n  baz := foo[\"bar\"]\n  // To delete an item from a map, you can use\n  delete(foo, \"bar\")\n```\n\nIf you try to retrieve the value for a key which does not exist in the map, it will return the zero\nvalue of the value type. This can confuse you, especially if the default value of your `ElementType`\n(for example, 0 for an int), is a valid value. To check whether a key exists in your map, you can\nuse\n\n```go\n  value, exists := foo[\"baz\"]\n  // If the key \"baz\" does not exist,\n  // value: 0; exists: false\n```\n\n## Time (from [exercism.org](https://exercism.org/tracks/go/concepts/time))\n\nA [`Time`][time] in Go is a type describing a moment in time. The date and time information can be\naccessed, compared, and manipulated through its methods, but there are also some functions called on\nthe `time` package itself. The current date and time can be retrieved through the [`time.Now`][now]\nfunction.\n\nThe [`time.Parse`][parse] function parses strings into values of type `Time`. Go has a special way\nof how you define the layout you expect for the parsing. You need to write an example of the layout\nusing the values from this special timestamp: **`Mon Jan 2 15:04:05 -0700 MST 2006`**.\n\nFor example:\n\n```go\nimport \"time\"\n\nfunc parseTime() time.Time {\n    date := \"Tue, 09/22/1995, 13:00\"\n    layout := \"Mon, 01/02/2006, 15:04\"\n\n    t, err := time.Parse(layout,date) // time.Time, error\n}\n\n// =\u003e 1995-09-22 13:00:00 +0000 UTC\n```\n\nThe [`Time.Format()`][format] method returns a string representation of time. Just as with the\n`Parse` function, the target layout is again defined via an example that uses the values from the\nspecial timestamp.\n\nFor Example:\n\n```go\nimport (\n    \"fmt\"\n    \"time\"\n)\n\nfunc main() {\n    t := time.Date(1995,time.September,22,13,0,0,0,time.UTC)\n    formattedTime := t.Format(\"Mon, 01/02/2006, 15:04\") // string\n    fmt.Println(formattedTime)\n}\n\n// =\u003e Fri, 09/22/1995, 13:00\n```\n\n### Layout Options\n\n\u003e [!NOTE]  \n\u003e All custom layouts must be defined using the values of this special timestamp:\n\u003e **`Mon Jan 2 15:04:05 -0700 MST 2006`** For example:\n\u003e\n\u003e ```go\n\u003e layout := \"1/2/2006 15:04:05\"\n\u003e layout := \"2006-January-2\"\n\u003e ```\n\nFor a custom layout use combination of these options. In Go predefined date and timestamp [format\nconstants][const] are also available.\n\n| Time        | Options                                        |\n| ----------- | ---------------------------------------------- |\n| Year        | 2006 ; 06                                      |\n| Month       | Jan ; January ; 01 ; 1                         |\n| Day         | 02 ; 2 ; \\_2 (For preceding 0)                 |\n| Weekday     | Mon ; Monday                                   |\n| Hour        | 15 ( 24 hour time format ) ; 3 ; 03 (AM or PM) |\n| Minute      | 04 ; 4                                         |\n| Second      | 05 ; 5                                         |\n| AM/PM Mark  | PM                                             |\n| Day of Year | 002 ; \\_\\_2                                    |\n\nThe `time.Time` type has various methods for accessing a particular time. e.g. Hour :\n[`Time.Hour()`][hour] , Month : [`Time.Month()`][month]. More on how this works can be found in the\n[official documentation][time].\n\nThe [`time`][time] includes another type, [`Duration`][duration], representing elapsed time, plus\nsupport for locations/time zones, timers, and other related functionality that will be covered in\nanother concept.\n\n[time]: https://golang.org/pkg/time/#Time\n[now]: https://golang.org/pkg/time/#Now\n[const]: https://pkg.go.dev/time#pkg-constants\n[format]: https://pkg.go.dev/time#Time.Format\n[hour]: https://pkg.go.dev/time#Time.Hour\n[month]: https://pkg.go.dev/time/#Time.Month\n[duration]: https://pkg.go.dev/time#Duration\n[parse]: https://golang.org/pkg/time/#Parse\n[article]: https://www.pauladamsmith.com/blog/2011/05/go_time.html\n\n## Range Iteration (from [exercism.org](https://exercism.org/tracks/go/concepts/range-iteration))\n\nIn Go, you can iterate over a `slice` using `for` and an index, or you can use `range`. `range` also\nallows you to iterate over a `map`.\n\nEvery iteration returns two values: the index/key and a copy of the element at that index/key.\n\n### Iterate over a slice\n\nEasy as pie, loops over a slice, ordered as expected.\n\n```go\narr := []int{10, 20, 30}\nfor i, x := range arr {\n  fmt.Println(i, x)\n}\n// outputs:\n// 0, 10\n// 1, 20\n// 2, 30\n```\n\n### Iterate over a map\n\nIterating over a map raises a new problem. The order is now random.\n\n```go\nhash := map[int]int{9: 10, 99: 20, 999: 30}\nfor k, v := range hash {\n  fmt.Println(k, v)\n}\n// outputs, for example:\n// 99 20\n// 999 30\n// 9 10\n```\n\n\u003e [!NOTE]  \n\u003e It may seem the above output is incorrect, as one would expect the first key/value pair on the\n\u003e declaration of the map `9 10` to be the first one printed and not the last. However, maps are\n\u003e unordered by nature - there isn't a first or last key/value pair. Because of that, when iterating\n\u003e over the entries of a map, the order by which entries will be visited will be random and not\n\u003e follow any specific pattern. This means the above output is possible but might differ from what\n\u003e you get if you try to run this yourself. To learn more about this see\n\u003e [Go Language Spec: range clause](https://go.dev/ref/spec#RangeClause).\n\n### Iteration omitting key or value\n\nIn Go an unused variable will raise an error at build time. Sometimes you only need the value, as\nper the first example:\n\n```go\narr := []int{10, 20, 30}\nfor i, x := range arr {\n  fmt.Println(x)\n}\n// Go build failed: i declared but not used\n```\n\nYou can replace the `i` with `_` which tells the compiler we don't use that value:\n\n```go\narr := []int{10, 20, 30}\nfor _, x := range arr {\n  fmt.Println(x)\n}\n// outputs:\n// 10\n// 20\n// 30\n```\n\nIf you want to only print the index, you can replace the `x` with `_`, or simply omit the\ndeclaration:\n\n```go\narr := []int{10, 20, 30}\n// for i, _ := range arr {\nfor i := range arr {\n  fmt.Println(i)\n}\n// outputs:\n// 0\n// 1\n// 2\n```\n\n## Type Definitions (from [exercism.org](https://exercism.org/tracks/go/concepts/type-definitions))\n\nWe've already seen struct types; to recap a `struct` is a sequence of named elements\ncalled *fields*, each field having a name and type. The name of a field must be unique within the\nstruct. Structs can be compared with the *class* in the Object Oriented Programming paradigm.\n\nYou create a new struct by using the `type` and `struct` keywords, then explicitly define the name\nand type of the fields as shown in the example below.\n\n```\ntype StructName struct{\n    field1 fieldType1\n    field2 fieldType2\n}\n```\n\n### Non-struct types\n\nYou've previously seen defining struct types. It is also possible to define non-struct types which\nyou can use as an alias for a built-in type declaration, and you can define receiver functions on\nthem to extend them in the same way as struct types.\n\n```go\ntype Name string\nfunc SayHello(n Name) {\n  fmt.Printf(\"Hello %s\\n\", n)\n}\nn := Name(\"Fred\")\nSayHello(n)\n// Output: Hello Fred\n```\n\nYou can also define non-struct types composed of arrays and maps.\n\n```go\ntype Names []string\nfunc SayHello(n Names) {\n  for _, name := range n {\n    fmt.Printf(\"Hello %s\\n\", name)\n  }\n}\nn := Names([]string{\"Fred\", \"Bill\"})\nSayHello(n)\n// Output:\n// Hello Fred\n// Hello Bill\n```\n\n## Pointers (from exercism.org)\n\nLike many other languages, Go has pointers. If you're new to pointers, they can feel a little\nmysterious but once you get used to them, they're quite straight-forward. They're a crucial part of\nGo, so take some time to really understand them.\n\nBefore digging into the details, it's worth understanding the use of pointers. Pointers are a way to\nshare memory with other parts of our program, which is useful for two major reasons:\n\n1. When we have large amounts of data, making copies to pass between functions is very inefficient.\n   By passing the memory location of where the data is stored instead, we can dramatically reduce\n   the resource-footprint of our programs.\n2. By passing pointers between functions, we can access and modify the single copy of the data\n   directly, meaning that any changes made by one function are immediately visible to other parts of\n   the program when the function ends.\n\n### Variables, Memory, and Pointers\n\nLet's say we have a regular integer variable `a`:\n\n```go\nvar a int\n```\n\nWhen we declare a variable, Go has to find a place in memory to store its value. This is largely\nabstracted from us — when we need to fetch the value stored in that piece of memory, we can just\nrefer to it by the variable name.\n\nFor instance, when we write `a + 2`, we are effectively fetching the value stored in the memory\nassociated with the variable `a` and adding 2 to it.\n\nSimilarly, when we need to change the value in the piece of memory of `a`, we can use the variable\nname to do an assignment:\n\n```go\na = 3\n```\n\nThe piece of memory that is associated with `a` will now be storing the value `3`.\n\nWhile variables allow us to refer to values in memory, sometimes it's useful to know the **memory\naddress** to which the variable is pointing. **Pointers** hold the memory addresses of those values.\nYou declare a variable with a pointer type by prefixing the underlying type with an asterisk:\n\n```go\nvar p *int // 'p' contains the memory address of an integer\n```\n\nHere we declare a variable `p` of type \"pointer to int\" (`*int`). This means that `p` will hold the\nmemory address of an integer. The zero value of pointers is `nil` because a `nil` pointer holds no\nmemory address.\n\n### Getting a pointer to a variable\n\nTo find the memory address of the value of a variable, we can use the `\u0026` operator. For example, if\nwe want to find and store the memory address of variable `a` in the pointer `p`, we can do the\nfollowing:\n\n```go\nvar a int\na = 2\n\nvar p *int\np = \u0026a // the variable 'p' contains the memory address of 'a'\n```\n\n### Accessing the value via a pointer (dereferencing)\n\nWhen we have a pointer, we might want to know the value stored in the memory address the pointer\nrepresents. We can do this using the `*` operator:\n\n```go\nvar a int\na = 2\n\nvar p *int\np = \u0026a // the variable 'p' contains the memory address of 'a'\n\nvar b int\nb = *p // b == 2\n```\n\nThe operation `*p` fetches the value stored at the memory address stored in `p`. This operation is\noften called \"dereferencing\".\n\nWe can also use the dereference operator to assign a new value to the memory address referenced by\nthe pointer:\n\n```go\nvar a int        // declare int variable 'a'\na = 2            // assign 'a' the value of 2\n\nvar pa *int\npa = \u0026a          // 'pa' now contains to the memory address of 'a'\n*pa = *pa + 2    // increment by 2 the value at memory address 'pa'\n\nfmt.Println(a)   // Output: 4\n                 // 'a' will have the new value that was changed via the pointer!\n```\n\nAssigning to `*pa` will change the value stored at the memory address `pa` holds. Since `pa` holds\nthe memory address of `a`, by assigning to `*pa` we are effectively changing the value of `a`!\n\nA note of caution however: always check if a pointer is not `nil` before dereferencing.\nDereferencing a `nil` pointer will make the program crash at runtime!\n\n```go\nvar p *int // p is nil initially\nfmt.Println(*p)\n// panic: runtime error: invalid memory address or nil pointer dereference\n```\n\n### Pointers to structs\n\nSo far we've only seen pointers to primitive values. We can also create pointers for structs:\n\n```go\ntype Person struct {\n    Name string\n    Age  int\n}\n\nvar peter Person\npeter = Person{Name: \"Peter\", Age: 22}\n\nvar p *Person\np = \u0026peter\n```\n\nWe could have also created a new `Person` and immediately stored a pointer to it:\n\n```go\nvar p *Person\np = \u0026Person{Name: \"Peter\", Age: 22}\n```\n\nWhen we have a pointer to a struct, we don't need to dereference the pointer before accessing one of\nthe fields:\n\n```go\nvar p *Person\np = \u0026Person{Name: \"Peter\", Age: 22}\n\nfmt.Println(p.Name) // Output: \"Peter\"\n                    // Go automatically dereferences 'p' to allow\n                    // access to the 'Name' field\n```\n\n## Slices and maps are already pointers\n\nSlices and maps are special types because they already have pointers in their implementation. This\nmeans that more often than not, we don't need to create pointers for these types to share the memory\naddress for their values. Imagine we have a function that increments the value of a key in a map:\n\n```go\nfunc incrementPeterAge(m map[string]int) {\n\tm[\"Peter\"] += 1\n}\n```\n\nIf we create a map and call this function, the changes the function made to the map persist after\nthe function ended. This is a similar behavior we get if we were using a pointer, but note how on\nthis example we are not using any referencing/dereferencing or any of the pointer syntax:\n\n```go\nages := map[string]int{\n  \"Peter\": 21\n}\nincrementPeterAge(ages)\nfmt.Println(ages)\n// Output: map[Peter:22]\n// The changes the function 'incrementPeterAge' made to the map are visible after the function ends!\n```\n\nThe same applies when changing an existing item in a slice.\n\nHowever, actions that return a new slice like `append` are a special case and **might not** modify\nthe slice outside of the function. This is due to the way slices work internally, but we won't cover\nthis in detail in this exercise, as this is a more advanced topic. If you are really curious you can\nread more about this in [Go Blog: Mechanics of 'append'][mechanics-of-append]\n\n[mechanics-of-append]: https://go.dev/blog/slices\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurgousset%2Fgo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Farthurgousset%2Fgo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Farthurgousset%2Fgo/lists"}