Go(lang)
I should contribute Go samples here: https://www.algorithm-archive.org/chapters/introduction/how_to_contribute.html
- https://medium.com/@arshamshirvani/super-charge-your-sublime-text-for-golang-development-3239d9c376bb
- https://github.com/nuance/GoTools
https://segment.com/blog/allocation-efficiency-in-high-performance-go-services/
http://eefret.me/making-sublime-your-golang-ide/
http://godashboard.appspot.com/project
Here is the whole spec. This is actually a really good quick refresher.
https://github.com/eawsy/aws-lambda-go
http://www.meetup.com/Ann-Arbor-Gophers/?scroll=true
https://github.com/gobwas/ws - Another websocket library.
https://github.com/dmulholland/clio/blob/master/go/example/main.go command line tool. I may like this better than the one I've been using.
Maybe this instead of gothic.
To-do / learn
- Go modules
- Create Android app
Libraries
Meta
- Thrust GUI using Chromium
- GTK3 GUI
- UI Native GUI, could be good for installers
- 2D/3D Math
- Go → JavaScript
- Notify File system watcher
- Cap'n Proto Very fast serialization
- Azul 3D Game Engine
- Sql tools
Web Frameworks
In the past I looked at Negroni, Goji, Gin and Beego. Did not like these. Want to look at
I should be able to get Gothic to play nice with them.
Other
Basics
- Uses func main (similar to C), a program also starts in package main
That thing you always forget
http://play.golang.org/p/rbuFUCsIY0
type foo []string
func (f *foo) Add(s string) {
*f = append(*f, s)
}
unsafe conversion
*(*int32)(unsafe.Pointer(&a))
coverage report
go test -coverprofile=coverage.out go tool cover -html=coverage.out -o=coverage.html
or
go test -coverprofile=coverage.out && go tool cover -html=coverage.out -o=coverage.html && rm coverage.out
https://golang.org/pkg/plugin/
Import
import ( "packageA" "packageB" )
- Unused imports throw an error
Functions
Basic
func add(x int, y int) int {
return x + y
}
Multi-return
func swap(a, b int) (int, int) {
return b, a
}
Named results
func sumProd(x, y int) (sum, prod) {
sum = x + y
prod = x * y
return
}
Function are values too and can be assigned, referenced and passed around.
Closure
func adder() func(int) int {
sum := 0
return func(x int) int {
sum += x
return sum
}
}
Variables
Go is strongly typed, but uses inference as much as possible. So this is possible
var x int x = 5
But better is
x := 5
Types
- bool
- string
- int{8,16,32,64}
- uint{8,16,32,64}, uintptr
- byte (same as uint8)
- rune (same as uint32, represents unicode point)
- float{32,64}
- complex{64,128}
Pointers
Go has pointers, but no pointer arithmetic.
v := Vertex{1,2}
p := &v
p.X = 5
Structs
A Struct (this can be set in package space, I don't know if it can be declared in a function)
type Vertex struct {
X int
Y int
}
v := Vertex{1,2}
fmt.Println(v.X)
A struct literal.
var ( name := "Adam" i := 1 )
Structs are the closes thing to classes in Go
Methods
Methods take a struct before the method name, this is the struct they are a method on
func(v *Vertex) Abs() float64 {
return math.Sqrt( v.X*v.X + v.Y*v.Y )
}
You can define a method for any type in your package, but not for a struct from another package.
Interfaces
Interfaces define a set of attribute. A struct satisfies an interface when it has all the attributes the interface defines. Golang.org reference
For
The only looping structure is for.
Traditional
for i := 0 ; i<10 ; i++ {
fmt.Println(i)
}
As While
i: = 5
for i<100 {
i += 3
}
Infinite Loop
for {
fmt.Println("There is no escape")
}
Range
a := []int{3,1,4,1,5,9,2,6,5}
for i,v := range a {
fmt.Println(i, v)
}
Range without index. This can be important because unused variables throw errors.
a := []int{3,1,4,1,5,9,2,6,5}
for _,v := range a {
fmt.Println(v)
}
If
Basic
func abs(x float64) float64 {
if x<0 {
return -x
}
return x
}
Much like for, there is a space for a statement scoped to the if block before the conditional
func pow(x, n, lim float64) float64 {
if v := math.Pow(x,n) ; v < lim {
return v
}
return lim
}
Else. Not shown here, but the pre-statement is scoped to the else block as well
if foo {
fmt.Println("Foo is true")
} else {
fmt.println("Foo is not true")
}
New
New allocates something and returns a pointer.
v := new(Vertex) x.X = 5
Maps
Like a dictionary, must be created with make
m = make(map[string]int) m["Adam"] = 28 m["Lauren"] = 26
Map literal
var m = map[string]int{
"Adam": 28,
"Lauren": 26,
}
var n = map[string]Vertex{
"Home": {10,20}
"Work": {25,40}
}
Delete (using previous examples)
delete(m, "Adam")
Slice
A slice points to a slice of an array. It does this with a pointer and a length
s: = []int{3,1,4,1,5,9,2,6}
Switch
switch pre := something; condition{
case "A":
// handle A
case "B":
//do B stuff
fallthrough
case "C":
//do stuff for C and B
default:
//default stuff
}
A switch with no condition evaluates each case, can act like a large if-else chain
switch{
case a > 10:
//do something
case a > 5:
//do something else
//this is actually 10 >= a > 5
default:
//all others, final else
}
Go Routines
I love these!
Prefix a function/method call with go and it's run in something like a thread, but with less overhead. Communication is done over channels
- ch := make{chan int}
- ch := make{chan int, 3} //make a channel with a buffer of length 3
- ch <- v //Send v to channel
- v := <-ch //Receive from channel and assign to v\
- close(c)
func sum(a []int, c chan int) {
sum := 0
for _, v := range a {
sum += v
}
c <- sum // send sum to c
}
...
c := make{chan int, 2}
go sum( []int{1,2,3,4,5}, c)
go sum( []int{6,7,8,9,10}, c)
x, y := <-c, <- c
A channel can be used a for range and the for will last as long as the channel is open Good Example. Closing isn't necessary, it will get garbage collected if appropriate, even when open.
Select
Select is like a switch but with channels for cases. It blocks until one of the cases is met (channel can read or write), then executes that block Documentation. Default works as expected, good for sleep is you don't want a select in a loop to consume too many resources.
Generics (and stuff)
Go doesn't have generics, or templates or convenient type casting. Instead, it does this.
Server Stuff
Install Golang
https://golang.org/doc/install
Gopath
export GOPATH=gopath (something like $HOME/go)
http://golang.org/doc/code.html#GOPATH
Exec
main.go
package main
import (
"bufio"
"fmt"
"os/exec"
)
func main() {
cmd := exec.Command("go", "run", "callme.go")
out, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
rd := bufio.NewReader(out)
cmd.Start()
s, _, _ := rd.ReadLine()
fmt.Println(string(s))
}
callme.go
package main
import (
"fmt"
)
func main() {
fmt.Println("Hello")
}
ScrewTypeSafety
func ScrewTypeSafety(i interface{}, o uintptr) {
p0 := unsafe.Pointer((uintptr)(unsafe.Pointer(&i)) + uintptr(8))
p1 := (*(*uintptr)(p0)) + o
*(*int)(unsafe.Pointer(p1)) = 70
}
Passing Slice Pointers
package main
import (
"fmt"
)
func main() {
var b []byte
mod(&b)
fmt.Println(b)
}
func mod(b *[]byte) {
f := []byte{12, 34}
*b = f
fmt.Println(f)
}