Go(lang): Difference between revisions
Adamcolton (talk | contribs) No edit summary |
Adamcolton (talk | contribs) No edit summary |
||
| Line 16: | Line 16: | ||
http://www.meetup.com/Ann-Arbor-Gophers/?scroll=true | http://www.meetup.com/Ann-Arbor-Gophers/?scroll=true | ||
https://github.com/gobwas/ws - Another websocket library. | |||
== Libraries == | == Libraries == | ||
Revision as of 14:26, 11 July 2017
Most references refer to the language as golang - go is too hard to search
I 'learned' Go once, forgot almost everything, came here for a refresher and found that I had crappy notes. So I'm rebuilding the notes in a way that should be useful to future-me.
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.
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
Web Frameworks
I need to find a good one, the best candidates seem to be:
No one has good videos on any of these. Fuck everyone.
Not impressed with Goji or Beego. Middleware in negroni looks nice, gin has the cleanest interface. I think I'll go with Gin, but I haven't found tutorials or anything like it yet.
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)
}
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)
}