"Go is an open source programming language that makes it easy to build simple, reliable, and efficient software."
The phrase above that you can find on golang.org is a perfect summary of a programming language that fills a huge gap in the software industry. Due to its simplicity, performance and user-friendliness, Go quickly became one of my favourite programming languages. There aren't too many languages out there that you can build a web server with a few lines of code after all:
package main
import (
"fmt"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Go is amazing %s!", r.URL.Path[1:])
}
func main() {
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8080", nil))
}
Go is Strongly Typed
Go, not only reduces the amount of code you have to write, it also supports pointers and it's a strongly typed language. The types of every object must be known at runtime:
var distanceUnit string = "m"
distance := 200
var ptrPerson *Person
ptrPerson.walk(distance, distanceUnit)
Gofmt
Gofmt allows you to focus on the code instead of the indentation or style of it using a single command:
go fmt path/to/your/package
Standard Packages
Standard packages/libraries have pretty good support for most things you need so you won't need to search for third party packages.
Single Executable
Go applications compile into a single executable binary that makes life much easier for developers. Also, this simplifies the distribution of software and allows containerization (Docker, etc.) of services.
Dep (Dependency Manager)
A popular but non-standard package manager that enables us to keep track of the versions of the packages we use in our application. Here is a well-written how-to guide.
Go uses Slices (Dynamic Arrays)
Slice is a very convenient dynamic array. Here is how to perform some operations on Slices:
// Iterate over slice
for i, v := range s { // use range, inc order
// i - index
// v - value
}
for i := 0; i < len(s); i++ { // use index, inc order
// i - index
// s[i] - value
}
for i := len(s)-1; i >= 0; i-- { // use index, reverse order
// i - index
// s[i] - value
}
// Function argument
func f(s []T) // s - passed by value, but memory the same
func f(s *[]T) // s - passed by refernce, but memory the same
// Append
a = append(a, b...)
// Clone
b = make([]T, len(a))
copy(b,a)
// Remove element, keep order
a = a[:i+copy(a[i:], a[i+1:])]
// or
a = append(a[:i], a[i+1:]...)
// Remove element, change order
a[i] = a[len(a)-1]
a = a[:len(a)-1]
Memory management with pools of objects
We can use thread safe pools to collect objects for reuse:
var p sync.Pool
var o *T
if v := p.Get(); v != nil {
o = v.(*T)
} else {
o = new(T)
}
// use o
p.Put(o) // return to reuse
Close Channel to Notify Multiple Listeners
Closing a channel will notify all the readers on that channel:
c := make(chan int)
for i := 0; i < 5; i++ {
go func(i int) {
_, ok := <-c
fmt.Printf("closed %d, %t\n", i, ok) // random order
}(i)
}
Inheritance
We can inherit the properties, methods of a struct by embedding it into another struct:
type A struct {
Id int
B // embed B struct
}
Concatenating and Building Strings in Go 1.10+
With the arrival of Go 1.10. It's now possible to use String Builder to create strings in an efficient way:
import (
"log"
"strings"
)
func main() {
s := "Hello "
log.Println(join(s, "World"))
}
func join(strs ...string) string {
var sb strings.Builder
for _, str := range strs {
sb.WriteString(str)
}
return sb.String()
}
Variadic Functions
Variadic functions can be called with any number of trailing arguments:
func variadicFunc(anotherArg int, args ...string) ([]string, int) {
var arr []string
for _, s := range args {
arr = append(arr, s)
}
return arr, anotherArg
}
func main() {
fmt.Println(variadicFunc(129471294, "1", "2", "3")) // ["1","2","3"]
}
That's all for now, feel free to leave a comment below, if you have anything to add or ask. Thank you and happy coding!
Disqus Comments Loading..