https://github.com/erik1066/golang-features
Features of the Go programming language.
https://github.com/erik1066/golang-features
examples features golang tutorial
Last synced: 12 months ago
JSON representation
Features of the Go programming language.
- Host: GitHub
- URL: https://github.com/erik1066/golang-features
- Owner: erik1066
- License: mit
- Created: 2019-03-08T00:45:42.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2019-03-11T01:17:32.000Z (over 7 years ago)
- Last Synced: 2025-01-26T11:27:48.215Z (over 1 year ago)
- Topics: examples, features, golang, tutorial
- Language: Go
- Homepage:
- Size: 14.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# Go Language Features
[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)_.
See [Pop!_OS setup guide](https://github.com/erik1066/pop-os-setup) for instructions on installing Go on Ubuntu 18.04.
Example "Hello, World!" application in GoLang:
```go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
```
> "fmt" is a package in Go. It's short for "format".
## Types
There are just a few basic types:
* `bool`
* `string`
* `int` (size depends on 32- or 64-bit arch), `int8`, `int16`, `int32`, `int64`
* `uint` (size depends on 32- or 64-bit arch), `uint8`, `uint16`, `uint32`, `uint64`, `uintptr`
* `byte` (alias for `uint8`)
* `rune` (alias for `int32`), basically meant as a `char` like in C++, C#, and Java
* `float32`, `float64`
* `complex64`, `complex128`
> Integer types are incompatible without explicit conversions. For example, an `int32` is incompatible with `int64` and vice-versa.
There are a few advanced types:
* Array
* Slice (like a `List` in C# and Java)
* Struct
* Pointer
* Function
* Interface
* Map (like a `Dictionary` in C# and `Map` in Java)
* Channel
## Variable Assignments
[Example code](src/variables/variables.go)
Go 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:
```go
var message string = "Hello, Go!"
```
The above is equivalent to:
```go
var message string
message = "Hello, Go!"
```
You 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:
```go
var message = "Hello, Go!"
```
You can alternatively delcare a variable and assign it without `var` by using the `:=` operator:
```go
message := "Hello, Go!"
```
Declaring and assigning multiple variables at the same time is possible:
```go
var a, b, c = 1, 2, 3
```
## Pointers
[Example code](src/pointers/pointers.go)
Pointers are declared using the `*` operator and dereferenced using the `&` operator.
```go
package main
import "fmt"
func main() {
name := "John"
var message *string = &name
fmt.Println(message) // prints a memory address
fmt.Println(*message) // prints "John"
/* Both name and message point to the same memory location. Changing one
therefore changes the other. For instance: */
*message = "Mary"
fmt.Println(name) // prints "Mary"
}
```
## User-defined types
[Example code](src/user-defined-types/user-defined-types.go)
Go has no concept of classes. Instead, class-like "structures" are created using the `type` keyword with the `struct` type:
```go
type Person struct {
name string
age int
}
```
A structure can be declared and assigned like such:
```go
package main
import "fmt"
type Person struct {
name string
age int
}
func main() {
var bob = Person{}
bob.name = "Bob"
bob.age = 45
fmt.Println(bob) // prints "{Bob 45}"
}
```
Note that we can alternatively use the following two syntax options to assign values to a user-defined type:
```go
var sandra = Person{"Sandra", 55}
fmt.Println(sandra) // prints "{Sandra 55}"
var maria = Person{age: 65, name: "Maria"}
fmt.Println(maria) // prints "{Maria 65}"
```
## Constants
[Example code](src/constants/constants.go)
```go
const (
Version = 1
OS = "Ubuntu 18.04"
)
```
## Loops
[Example code](src/loops/loops.go)
There's only one loop syntax in Go: `for`. There is no `do`, `while`, or `foreach`. The `for` syntax can take several forms:
```go
// traditional for loop
for initialization; condition; after {
// statements
}
// equivalent to a while loop
for condition {
// statements
}
// equivalent to an infinite loop
for {
// statements
}
```
Example of the the traditional `for`:
```go
package main
import "fmt"
func main() {
names := [3]string{"John", "Mary", "Susan"} // creates an array
for i := 0; i < len(names); i++ {
fmt.Println(names[i])
}
}
```
Loops in Go can be terminated using `break` or `return`.
## Ranges
[Example code](src/ranges/ranges.go)
A 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":
```go
places := make([]string, 6) // create a slice
places[0] = "New York City"
places[1] = "Los Angeles"
places[2] = "Chicago"
places[3] = "Toronto"
places[4] = "Victoria"
places[5] = "Seattle"
canadianPlaces := places[3:5]
for i := 0; i < len(canadianPlaces); i++ {
fmt.Println(canadianPlaces[i])
}
```
We 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".
```go
for i, place := range places[:3] {
fmt.Println(i+1, place)
}
```
In 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.
A 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:
```go
otherPlaces := places[5:]
for _, place := range otherPlaces {
fmt.Println(place)
}
```
Leaving the end value of the rage unspecified, as shown above, is shorthand for "take all the remaining elements".
## Variadic functions
[Example code](src/variadic-functions/variadic-functions.go)
A "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:
```go
func Greeting(name string, messages ...string) {
for _, message := range messages {
fmt.Println(message, name)
}
}
func main() {
Greeting("Andy", "Hello", "Greetings", "Salutations")
}
```
Output:
```
Hello Andy
Greetings Andy
Salutations Andy
```
## Multiple return values
[Example code](src/multiple-return-values/multiple-return-values.go)
Go can return multiple named values from a function:
```go
func CreateGreeting(name string) (primary string, alternate string) {
primary = "Hello, " + name
alternate = "Greetings, " + name
return
}
func main() {
greeting, alternate := CreateGreeting("Andy")
fmt.Println(greeting)
fmt.Println(alternate)
}
```
Output:
```
Hello, Andy
Greetings, Andy
```
In 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.
## Passing functions to functions
[Example code](src/passing-a-function/passing-a-function.go)
Go 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`.
```go
package main
import "fmt"
func CreateGreeting(name string, generator func(string) string) string {
greeting := generator(name)
return greeting
}
func CreateGreeting1(name string) string {
return "Greetings, " + name + "!"
}
func CreateGreeting2(name string) string {
return "Hello, " + name
}
func main() {
greeting1 := CreateGreeting("Andy", CreateGreeting1)
fmt.Println(greeting1)
greeting2 := CreateGreeting("Andy", CreateGreeting2)
fmt.Println(greeting2)
}
```
Output:
```
Greetings, Andy!
Hello, Andy
```
## Methods
[Example code](src/methods/methods.go)
Methods operate on defined `struct` types. They are implemented by specifying the type in parenthesis prior to the name of the method. For example:
```go
type Person struct {
name string
}
func (person Person) Greet() {
fmt.Println("Hello, " + person.name)
}
func main() {
person := Person{"John"}
person.Greet()
}
```
Observe 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`.
However, 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:
```go
type Person struct {
name string
}
func (person *Person) SetName(name string) {
person.name = name
}
func main() {
person := Person{"John"}
person.SetName("Dinah")
fmt.Println(person.name) // prints "Dinah"
}
```
## Interfaces
[Example code](src/interfaces/interfaces.go)
Any type that has the same methods as an interface implements that interface. We can then use that type anywhere that interface is required.
In 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.
```go
package main
import (
"fmt"
"strings"
)
type uppercaser struct {
data string
}
type reverser struct {
data string
}
type transformer interface {
transform() string
}
func (t reverser) transform() string {
runes := []rune(t.data)
for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
runes[i], runes[j] = runes[j], runes[i]
}
return string(runes)
}
func (t uppercaser) transform() string {
var upper = strings.ToUpper(t.data)
return upper
}
func transformData(t transformer) {
fmt.Println(t.transform())
}
func main() {
var reverser = reverser{data: "John"}
var uppercaser = uppercaser{data: "Dinah"}
transformData(reverser) // outputs "nhoJ"
transformData(uppercaser) // outputs "DINAH"
}
```