Using Go
Go Fundamentals
Authors
Designed by Ken Thompson, Rob Pike and Robert Griesemer. Ken Thompson helped design C, Unix, UTF-8. Rob Pike also worked on Unix and UTF-8. Robert Greisemer created the Hotspot JVM.
Motivation
To address the following:
- Efficient compilation
- Efficient execution
- Ease of programming
At Google the use of C++, Java and Python did not give all the three behaviors combined.
Python (Efficient compilation, ease of programming)
C++ (Efficient execution)
Java (Better compilation than C++)
The authors (while at google) therefore created Go which aims to provide efficient compilation, efficient (fast) execution, and be simple to program in.
More details:
https://app.pluralsight.com/library/courses/go-big-picture
Setup
Visual Studio Code
Add Go extensions
Ctrl + Shift + X
Go (Microsoft extensions)
Ctrl + Shift + P
go install/update
select all tick box -> ok
Path Set up
You can also run VS Code from the terminal by typing 'code' after adding it to the path.
Launch VS Code. Open the Command Palette (Ctrl+Shift+P) and type 'shell command' to find the Shell Command: Install 'code' command in PATH command
Auto Save
Settings: Ctrl + ,
Files: Auto Save > onFocusChange
Terminal
Ctrl + Shift + '
Debug/Run
Ctrl + F5
Click on configure cog wheel. Change "program": "${fileDirname}" to "program": "${file}"
Ctrl + Shift + F5 (Stop Debug)
Golang Installation
Install to C:\go
Add Workspace
Eg %USERPROFILE%\code\go-ws
Create bin, pkg and src folder here
Set environment variable GOPATH to point to the go workspace
In gitbash:
setx GOPATH ~/code/go-ws
Run
go get github.com/golang/example/hello
$GOPATH/bin/hello
Hello, Go examples!
More details:
https://app.pluralsight.com/library/courses/getting-started-with-go
Modules
$ go mod init gitlab.com/lightphos/codeclub/server
If you get this
go: modules disabled inside GOPATH/src by GO111MODULE=auto; see 'go help modules'
then
$ export GO111MODULE="on"
and try again
then
$ go build .
$ ls
go.mod main.exe main.go server.exe
$./server.exe
On windows, the server will not run if there is another process with the same name already running.
Testing
To add unit tests right click on function select
generate unit tests
May be prompted to install extensions, go ahead and install.
This will create a corresponding <>_test.go file
$ go test *.go
Coverage
go test -cover
Performance (Benchmark)
Documentation
Simple Web Server
Create a file main.go in directory $GOPATH/src/gitlab.com/lightphos/codeclub
package main
import (
"fmt"
"net/http"
)
func main() {
http.HandleFunc("/", HelloServer)
http.ListenAndServe(":8080", nil)
}
// HelloServer server
func HelloServer(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, %s!", r.URL.Path[1:])
}
go run main.go
point your browser to http://localhost:8080/coders
Basic Constructs
Primitives
Declaration:
var i int
i = 1
or
var f float32 = 2.178
or
s := "String"
Note you must use a variable if declared otherwise the compiler will complain.
Some other types:
string, complex, byte, uint
Pointers
* - contents of an address (a reference)
& - address of a value/variable
i := 7
p := &i // address of i
fmt.Println(*p) // print out the contents of the address at p
*p = 9 // change the contents of the address at P to 9
fmt.Println(i) // i is now 9
z := &p
fmt.Println(**z)
> 9
However unlike C/C++ no pointer arithmetic.
Constants
const Pi = 3.1415
const c int = 1
With Iota
const (
a = iota // 0
b = iota // 1
c // 2 - no need to keep writing iota
)
// increments the const variables if they within a common const block
fmt.Println(a, b, c)
> 0 1 2
Collections
Arrays, Slices, Maps, Structs
var arr [3]int
arr[0] = 1
arr[1] = 2
arr[2] = 3
or
arr := []int{1, 2, 3}
fmt.Println(arr)
$ [1 2 3]
Arrays are fixed length while slices can be extended
Slice from array
slice := arr[:] // from 0 to the end
Slice from scratch
slice := []int{1,2,3}
Extend
slice = append(slice, 4, 5)
Select parts
s2 := slice[1:] from 1 to end
s3 := slice[:2] // from 0 to < 2
s4 := slice[2:5] // from 2 to 4
m := map[string]int{"a":11, "b":12} // key is string value is int
fmt.Println(m["b"]) // 12
delete(m, "a") // remove entry
Struct a collection of possibly different types.
type User struct {
id int
name string
}
fred := User{1, "Fred Flintstone"}
fred.id = 2
wilma := User{name:"Wilma Flintstone"}
pebbles := &User{3, "Pebbles Flintstone"}
fmt.Println(pebbles)
> &{3 Pebbles Flintstone}
(*pebbles).id = 4 // or
pebbles.id = 4
Functions/Methods
func afunc() {
fmt.Println("a func")
}
// func afunc(s string) // cannnot overload !!!
Method modifies a struct
func (u User) afunc() {
fmt.Println(u)
}
func (u User) concat(s string) {
fmt.Println(u.name, s)
}
pebbles.concat(s)
> Pebbles Flintstone was here
fmt.Println(pebbles)
> &{2 Pebbles Flintstone} # no change to original struct
To modify struct use a pointer
func (u *User) change(name string) {
u.name = name
}
pebbles.change("new name")
fmt.Println(pebbles)
> &{2 new name} # struct modified
To make a function/method/struct public the initial letter of the name needs to be in capitals, this includes any fields in a struct.
func (u User) Concat(s) ....
Control
if name == "name" {
fmt.Println("name is name")
}
if u := User{1, "name"}; u.name == "name" {
fmt.Println("username is name")
}
Packages
All go programs need a package. If main then an executable will be created. The main function being the entry point. If any other package than an archive (.a) file will be created in the pkg directory.
src -> domain -> user.go
package domain
import "strings"
type User struct {
Id int
Name string
}
func (u User) Upper() User {
u.Name = strings.ToUpper(u.Name)
return u
}
package reflects directory in which the code lives, though not necessarily (as in main).
Note the method has init caps to be publicly accessible. Lowercase methods are accessible if in the same package.
The Upper method has no parameters but returns User.
Another way would be to modify the structure using a pointer *User.
func (u *User) ChangeToUpper() {
u.Name = strings.ToUpper(u.Name)
}
Usage: Note the import. With the correct extensions VSC will auto import.
package main
import (
"fmt"
"gitlab.com/lightphos/codeclub/domain"
)
func main() {
u := domain.User{1, "name"}
fmt.Println(u.Upper())
un := domain.User{2, "new name"}
un.ChangeToUpper()
fmt.Println(un)
}
> {1 NAME}
> {2 NEW NAME}
Packages can be committed to repositories such as Github, and a copy is downloaded using go get '=<repo url>
Modules and Versioning
go mod init
go mod edit -require github.com/wilk/uuid@0.0.1
Interfaces
Collection of methods that an object can meet and therefore be a type of that interface.
package access
type OID string
type Info struct {
Item string
}
type Access interface {
Open()
Close()
Find(oid OID) (Info, error)
}
To 'implement' the interface Access, all you need to do is provide all the methods in the interface.
type Db struct {
id int
}
func (db Db) Open() {
fmt.Println("Open")
}
func (db Db) Close() {
fmt.Println("Close")
}
func (db Db) Find(oid OID) (Info, error) {
inf := Info{"item"}
return inf, nil
}
func DbEngine() {
var a Access = Db{1} // Db can be assigned to Access type
a.Open()
f, _ := a.Find("s")
fmt.Println(f)
a.Close()
}
Defer, will run the a.Close at the end of the scope of the function:
func DbEngine() {
var a Access = Db{1} // Db can be assigned to Access type
defer a.Close()
a.Open()
f, _ := a.Find("s")
fmt.Println(f)
}
Common Libraries
https://golang.org/pkg/strings/#pkg-overview
https://golang.org/pkg/net/http/
Go with VueJS
VueJs
Install chocolatey <https://chocolatey.org/>
Then node
choco install nodejs-lts (10.6.0)
Then
npm install vue -g
Wails (Desktop)
https://medium.com/js-dojo/building-a-desktop-app-in-go-using-wails-b7f5825f986a
Mongo
CockroachDb
Google App Engine Server
See appengine-hello in src/github/golang/example