{"id":21842478,"url":"https://github.com/erik1066/golang-features","last_synced_at":"2025-06-28T10:33:43.876Z","repository":{"id":96784865,"uuid":"174442966","full_name":"erik1066/golang-features","owner":"erik1066","description":"Features of the Go programming language.","archived":false,"fork":false,"pushed_at":"2019-03-11T01:17:32.000Z","size":15,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-26T11:27:48.215Z","etag":null,"topics":["examples","features","golang","tutorial"],"latest_commit_sha":null,"homepage":"","language":"Go","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/erik1066.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":"2019-03-08T00:45:42.000Z","updated_at":"2019-03-11T01:17:33.000Z","dependencies_parsed_at":null,"dependency_job_id":"8e756e56-2841-4d88-b437-5f2b038ad8b3","html_url":"https://github.com/erik1066/golang-features","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erik1066%2Fgolang-features","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erik1066%2Fgolang-features/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erik1066%2Fgolang-features/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/erik1066%2Fgolang-features/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/erik1066","download_url":"https://codeload.github.com/erik1066/golang-features/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244825654,"owners_count":20516592,"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":["examples","features","golang","tutorial"],"created_at":"2024-11-27T22:12:05.603Z","updated_at":"2025-03-21T16:14:23.880Z","avatar_url":"https://github.com/erik1066.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Go Language Features\n\n[Go by Example](https://gobyexample.com/) is an excellent syntax reference. If you're new to Go, check out the free online book _[An Introduction to Programming in Go](http://www.golang-book.com/books/intro)_. \n\nSee [Pop!_OS setup guide](https://github.com/erik1066/pop-os-setup) for instructions on installing Go on Ubuntu 18.04.\n\nExample \"Hello, World!\" application in GoLang:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n    fmt.Println(\"Hello, World!\")\n}\n```\n\n\u003e \"fmt\" is a package in Go. It's short for \"format\".\n\n## Types\n\nThere are just a few basic types:\n\n* `bool`\n* `string`\n* `int` (size depends on 32- or 64-bit arch), `int8`, `int16`, `int32`, `int64`\n* `uint` (size depends on 32- or 64-bit arch), `uint8`, `uint16`, `uint32`, `uint64`, `uintptr`\n* `byte` (alias for `uint8`)\n* `rune` (alias for `int32`), basically meant as a `char` like in C++, C#, and Java\n* `float32`, `float64`\n* `complex64`, `complex128`\n\n\u003e Integer types are incompatible without explicit conversions. For example, an `int32` is incompatible with `int64` and vice-versa.\n\nThere are a few advanced types:\n\n* Array\n* Slice (like a `List` in C# and Java)\n* Struct\n* Pointer\n* Function\n* Interface\n* Map (like a `Dictionary` in C# and `Map` in Java)\n* Channel\n\n## Variable Assignments\n\n[Example code](src/variables/variables.go)\n\nGo has three methods for declaring and/or assigning variables. The first is to declare a variable using `var`, provide a variable name, define the type, an assignment operator, and then optionally the value you want to assign after the operator. For example:\n\n```go\nvar message string = \"Hello, Go!\"\n```\n\nThe above is equivalent to:\n\n```go\nvar message string\nmessage = \"Hello, Go!\"\n```\n\nYou can optionally omit the `string` from the first example because the right-hand side of the `=` operator implies this is a `string`. Go is intelligent enough to figure out the type based on the right-hand side of the operator, much like C# and Java. Hence the following example is legal:\n\n```go\nvar message = \"Hello, Go!\"\n```\n\nYou can alternatively delcare a variable and assign it without `var` by using the `:=` operator:\n\n```go\nmessage := \"Hello, Go!\"\n```\n\nDeclaring and assigning multiple variables at the same time is possible:\n\n```go\nvar a, b, c = 1, 2, 3\n```\n\n## Pointers\n\n[Example code](src/pointers/pointers.go)\n\nPointers are declared using the `*` operator and dereferenced using the `\u0026` operator.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n    name := \"John\"\n    var message *string = \u0026name\n    fmt.Println(message)  // prints a memory address\n    fmt.Println(*message) // prints \"John\"\n\n    /* Both name and message point to the same memory location. Changing one\n       therefore changes the other. For instance: */\n\n    *message = \"Mary\"\n    fmt.Println(name)  // prints \"Mary\"\n}\n```\n\n## User-defined types\n\n[Example code](src/user-defined-types/user-defined-types.go)\n\nGo has no concept of classes. Instead, class-like \"structures\" are created using the `type` keyword with the `struct` type:\n\n```go\ntype Person struct {\n    name string\n    age  int\n}\n```\n\nA structure can be declared and assigned like such:\n\n```go\npackage main\n\nimport \"fmt\"\n\ntype Person struct {\n    name string\n    age  int\n}\n\nfunc main() {\n    var bob = Person{}\n    bob.name = \"Bob\"\n    bob.age = 45\n\n    fmt.Println(bob) // prints \"{Bob 45}\"\n}\n```\n\nNote that we can alternatively use the following two syntax options to assign values to a user-defined type:\n\n```go\nvar sandra = Person{\"Sandra\", 55}\nfmt.Println(sandra) // prints \"{Sandra 55}\"\n\nvar maria = Person{age: 65, name: \"Maria\"}\nfmt.Println(maria) // prints \"{Maria 65}\"\n```\n\n## Constants\n\n[Example code](src/constants/constants.go)\n\n```go\nconst (\n    Version = 1\n    OS      = \"Ubuntu 18.04\"\n)\n```\n\n## Loops\n\n[Example code](src/loops/loops.go)\n\nThere's only one loop syntax in Go: `for`. There is no `do`, `while`, or `foreach`. The `for` syntax can take several forms:\n\n```go\n// traditional for loop\nfor initialization; condition; after {\n    // statements\n}\n\n// equivalent to a while loop\nfor condition {\n    // statements\n}\n\n// equivalent to an infinite loop\nfor {\n    // statements\n}\n```\n\nExample of the the traditional `for`:\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc main() {\n\tnames := [3]string{\"John\", \"Mary\", \"Susan\"} // creates an array\n\n\tfor i := 0; i \u003c len(names); i++ {\n\t\tfmt.Println(names[i])\n\t}\n}\n```\n\nLoops in Go can be terminated using `break` or `return`.\n\n## Ranges\n\n[Example code](src/ranges/ranges.go)\n\nA subset of a collection can be obtained using the range sytnax `[start..end]`. For example, the loop below prints just the Canadian city names \"Toronto\" and \"Victoria\":\n\n```go\nplaces := make([]string, 6) // create a slice\nplaces[0] = \"New York City\"\nplaces[1] = \"Los Angeles\"\nplaces[2] = \"Chicago\"\nplaces[3] = \"Toronto\"\nplaces[4] = \"Victoria\"\nplaces[5] = \"Seattle\"\n\ncanadianPlaces := places[3:5]\n\nfor i := 0; i \u003c len(canadianPlaces); i++ {\n    fmt.Println(canadianPlaces[i])\n}\n```\n\nWe can also just print the big U.S. cities in the list by using special `for` syntax as shown below. Notice the abscence of the starting value for the range. Leaving the start value unspecified is shorthand for \"start at the beginning\".\n\n```go\nfor i, place := range places[:3] {\n    fmt.Println(i+1, place)\n}\n```\n\nIn the above example, `i` is the index value and `place` is the value of the slice at that index. Both variables can then be used in the loop body.\n\nA problem arises when we do not need to use `i` in the loop body: Go will refuse to compile our code if there is an unused variable. In those situations we can use the `_` operator in place of `i` to avoid a compile-time error:\n\n```go\notherPlaces := places[5:]\nfor _, place := range otherPlaces {\n    fmt.Println(place)\n}\n```\n\nLeaving the end value of the rage unspecified, as shown above, is shorthand for \"take all the remaining elements\".\n\n## Variadic functions\n\n[Example code](src/variadic-functions/variadic-functions.go)\n\nA \"variadic function\" is one that accepts a variable number of parameters of a specific type. Use the `...` operator to specify that a method parameter is variadic:\n\n```go\nfunc Greeting(name string, messages ...string) {\n\tfor _, message := range messages {\n\t\tfmt.Println(message, name)\n\t}\n}\n\nfunc main() {\n\tGreeting(\"Andy\", \"Hello\", \"Greetings\", \"Salutations\")\n}\n```\n\nOutput:\n\n```\nHello Andy\nGreetings Andy\nSalutations Andy\n```\n\n## Multiple return values\n\n[Example code](src/multiple-return-values/multiple-return-values.go)\n\nGo can return multiple named values from a function:\n\n```go\nfunc CreateGreeting(name string) (primary string, alternate string) {\n\tprimary = \"Hello, \" + name\n\talternate = \"Greetings, \" + name\n\treturn\n}\n\nfunc main() {\n\tgreeting, alternate := CreateGreeting(\"Andy\")\n\tfmt.Println(greeting)\n\tfmt.Println(alternate)\n}\n```\n\nOutput:\n\n```\nHello, Andy\nGreetings, Andy\n```\n\nIn the above example, `primary` and `alternate` are the named return values. Observe that they're wrapped in parenthesis after the method signature and before the opening brace.\n\n## Passing functions to functions\n\n[Example code](src/passing-a-function/passing-a-function.go)\n\nGo allows passing a function to another function. Passing functions is a matter of declaring the function-to-be-passed in the receiving function's signature. We can see this in the example below where how the `generator` parameter is declared as a function that accepts a `string` and returns a `string`. We can then supply any function that meets those requirements to `CreateGreeting`.\n\n```go\npackage main\n\nimport \"fmt\"\n\nfunc CreateGreeting(name string, generator func(string) string) string {\n\tgreeting := generator(name)\n\treturn greeting\n}\n\nfunc CreateGreeting1(name string) string {\n\treturn \"Greetings, \" + name + \"!\"\n}\n\nfunc CreateGreeting2(name string) string {\n\treturn \"Hello, \" + name\n}\n\nfunc main() {\n\tgreeting1 := CreateGreeting(\"Andy\", CreateGreeting1)\n\tfmt.Println(greeting1)\n\n\tgreeting2 := CreateGreeting(\"Andy\", CreateGreeting2)\n\tfmt.Println(greeting2)\n}\n```\n\nOutput:\n\n```\nGreetings, Andy!\nHello, Andy\n```\n\n## Methods\n\n[Example code](src/methods/methods.go)\n\nMethods operate on defined `struct` types. They are implemented by specifying the type in parenthesis prior to the name of the method. For example:\n\n```go\ntype Person struct {\n\tname    string\n}\n\nfunc (person Person) Greet() {\n\tfmt.Println(\"Hello, \" + person.name)\n}\n\nfunc main() {\n\tperson := Person{\"John\"}\n\tperson.Greet()\n}\n```\n\nObserve that `Greet()` is called on an instance of `Person` using the `.` operator. `Greet()` also has `(person Person)` prior to the method name, specifying that this method only operates on `Person`.\n\nHowever, the `Greet()` method will not be able to modify any values on the `person` instance that was passed to it, as `person` was passed by value and not by reference. To modify the instance being operated on we can use a pointer:\n\n```go\ntype Person struct {\n\tname    string\n}\n\nfunc (person *Person) SetName(name string) {\n\tperson.name = name\n}\n\nfunc main() {\n\tperson := Person{\"John\"}\n\tperson.SetName(\"Dinah\")\n\tfmt.Println(person.name) // prints \"Dinah\"\n}\n```\n\n## Interfaces\n\n[Example code](src/interfaces/interfaces.go)\n\nAny type that has the same methods as an interface implements that interface. We can then use that type anywhere that interface is required.\n\nIn the example below, the interface `transformer` is defined as having a method called `transform` that outputs a string. Both `reverser` and `uppercaser` implement the `transformer` interface by conversion, since they each have a method that meets the interface definition. We can then use an instance of either `reverser` or `uppercaser` as an argument to the `transformData` function, which expects an interface.\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"strings\"\n)\n\ntype uppercaser struct {\n\tdata string\n}\n\ntype reverser struct {\n\tdata string\n}\n\ntype transformer interface {\n\ttransform() string\n}\n\nfunc (t reverser) transform() string {\n\trunes := []rune(t.data)\n\tfor i, j := 0, len(runes)-1; i \u003c j; i, j = i+1, j-1 {\n\t\trunes[i], runes[j] = runes[j], runes[i]\n\t}\n\treturn string(runes)\n}\n\nfunc (t uppercaser) transform() string {\n\tvar upper = strings.ToUpper(t.data)\n\treturn upper\n}\n\nfunc transformData(t transformer) {\n\tfmt.Println(t.transform())\n}\n\nfunc main() {\n\tvar reverser = reverser{data: \"John\"}\n\tvar uppercaser = uppercaser{data: \"Dinah\"}\n\n\ttransformData(reverser) // outputs \"nhoJ\"\n\ttransformData(uppercaser) // outputs \"DINAH\"\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferik1066%2Fgolang-features","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ferik1066%2Fgolang-features","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ferik1066%2Fgolang-features/lists"}