GoLang


http://golang.org/doc/       
Some package links: http://golang.org/pkg/strings/    http://golang.org/pkg/sync/    http://golang.org/pkg/os/   http://golang.org/pkg/runtime/     http://golang.org/pkg/net/    http://golang.org/pkg/io/    http://golang.org/pkg/fmt/      http://golang.org/pkg/bufio/  


HelloWorld
package main

import "fmt"

func main() {
    fmt.Printf("hello, world\n")
}


$ go run hello.go
hello, world
--------------------------------------
package main

import (                            //parenthesis for multiple import or multiple const, etc
    "fmt"
    "math"
)

func main() {
    fmt.Println("Happy", math.Pi, "Day")
}

package main

import "fmt"

func add(x int, y int) int {                   //function, type after operand
    return x + y                    //When two or more consecutive named function parameters share a type, you can omit the type from all but the last.
}                                                  //add(x, y int)

func main() {
    fmt.Println(add(42, 13))
}

func split(sum int) (x, y int) {        //return multiple named values
    x = sum * 4 / 9
    y = sum - x
    return
}

7 10

var declares a list of variables.   //var x, y, z int
var x, y, z int = 1, 2, 3      //var c, python, java = true, false, "no!"
:=  instead of var for implicit types            c, python, java := true, false, "no!"
(outside a function every construct begins with a keyword and the := construct is not available.)

Datatypes

package main

import (
    "fmt"
    "math/cmplx"
)

var (
    ToBe   bool       = false
    MaxInt uint64     = 1<<64 - 1                                  //float:           z := float64(1)        z := 1.0
    z      complex128 = cmplx.Sqrt(-5 + 12i)
)

const (
    Big   = 1 << 100
    Small = Big >> 99
)

func main() {
    const f = "%T(%v)\n"
    fmt.Printf(f, ToBe, ToBe)
    fmt.Printf(f, MaxInt, MaxInt)
    fmt.Printf(f, z, z)
}

bool(false)
uint64(18446744073709551615)
complex128((2+3i))
bool     string      int  int8  int16  int32  int64      uint uint8 uint16 uint32 uint64 uintptr        byte // alias for uint8    rune // alias for int32     // represents a Unicode code point        float32 float64     complex64 complex128

interface that implements one method is ended in "er"  e.g. interface Stringer implements method String()
In packages a name is exported if it begins with a capital letter.  e.g. fmt.Println 

 Numeric constants are high-precision values.  An untyped constant takes the type needed by its context.  Try printing needInt(Big) too.
const (
    Big   = 1 << 100
    Small = Big >> 99
)

func needInt(x int) int { return x*10 + 1 }
func needFloat(x float64) float64 {
    return x * 0.1
}

func main() {   

    fmt.Println(needInt(Small))
    fmt.Println(needFloat(Small))
    fmt.Println(needFloat(Big))}

21
0.2
1.2676506002282295e+29

for/if

sum := 0
for i := 0; i < 10; i++ {             //  sum := 1   for sum < 1000 {}   //for {}  forever loop
    sum += i
}

if x < 0 {                     // if v := math.Pow(x, n); v < lim {            //a variable only for if (like for for loop) or any of its else blocks
        return math.Sqrt(-x) + "i"
} else { return 0}

Switch
func main() {
    switch os := runtime.GOOS; os {
    case "darwin":   fmt.Println("OS X.")
    case "linux":      fmt.Println("Linux.")
    default:              fmt.Printf("%s.", os)
    }
}

Switch cases evaluate cases from top to bottom, stopping when a case succeeds. (For example,
switch i {
case 0:
case f():
}
does not call f if i==0.)
 Switch without a condition is the same as switch true. This construct can be a clean way to write long if-then-else chains.
switch {
    case t.Hour() < 12:        fmt.Println("Good morning!")
    case t.Hour() < 17:        fmt.Println("Good afternoon.")
    default:        fmt.Println("Good evening.")
    }



Struct

type Vertex struct {
    X int
    Y int
}

func main() {
    v := Vertex{1, 2}     to inititalize only one param:    d = Vertex{Y:1}  
    v.X = 4
        q := &v             //pointer
        q.X = 5
    fmt.Println(v, q)
}

{5 2} &{5 2}

type Vertex struct {
    X, Y int
}

var (
    p = Vertex{1, 2}  // has type Vertex
    q = &Vertex{1, 2} // has type *Vertex     // The special prefix & constructs a pointer to a struct literal.
    r = Vertex{Y: 1}  // X:0 is implicit    order is not important
    s = Vertex{}      // X:0 and Y:0
)

func main() {
    fmt.Println(p, q, r, s)
}
{1 2} &{1 2} {0 1} {0 0}

new(T) allocates a zeroed T value and returns a pointer to it.
v := new(Vertex) //OR var t *T = new(T) t is struct type and t is a pointer to the struct
fmt.Println(v)
v.X, v.Y = 11, 9
fmt.Println(v)

&{0 0}
&{11 9}


Slice vs Array

 []T is a slice with elements of type T.
p := []int{2, 3, 5, 7, 11, 13}               p[i]        p[1:4]   //subslice   (subarray)        len(p), cap(p)  //current length, capacity(maximum length)                 a := make([]int, 5)  ==>  [0 0 0 0 0]
b := make([]int, 0, 5)
printSlice("b", b)
c := b[:2]
printSlice("c", c)
d := c[2:5]
printSlice("d", d)

b len=0 cap=5 []
c len=2 cap=5 [0 0]
d len=3 cap=3 [0 0 0]

var z []int     if z == nil {}       A nil slice has a length and capacity of 0

var pow = []int{1, 0, 4, 11, 13}

func main() {
    for i, v := range pow {      iterate over a slice and along with values
                                              skip the index or value by assigning to _.            for _, value := range pow {}
        fmt.Printf("%d = %d\n", i, v)
    }
}

0 = 1
1 = 0
2 = 4
3 = 11
4 = 13
Multi-dimensional Slice
func Pic(dx, dy int) [][]uint8 {
    a := make([][]uint8, dy)
    i :=0
    for i < dy{
        a[i] = make([]uint8, dx)
        i=i+1
    }

        for i:=0;i<dy;i = i+1{
        for j:= 0; j<dx; j++{
            a[i][j] = uint8((i+j)/2)
        }
        }

    return a
}

var bigDigits = [][]string{
   {"  000  ",
    " 0   0 ",
    "0     0",
    "0     0",
    "0     0",
     "0  0",
     " 000 "},
    {" 1 ", "11 ", " 1 ", " 1 ", " 1 ", " 1 ", "111"},
    {"222","2  2","  2","  2 ","2  ","2  ","22222"},
    // ... 3 to 8 ...
    {" 9999", "9  9", "9  9", " 9999", "  9", "  9", "  9"},
}

Append
x := []int{1,2,3}
x = append(x, 4, 5, 6)
fmt.Println(x)

prints [1 2 3 4 5 6]

That is a slice:                                                              <<SLICE vs ARRAY>>

var av = []int{1,5,2,3,7}

And those are arrays:

var av = [...]int{1,5,2,3,7}
var bv = [5]int{1,5,2,3,7}

If you try to compile:

var av = [...]int{1,5,2,3,7}
fmt.Println(av)
sort.Ints(av)
fmt.Println(av)

, you will get an error:

cannot use av (type [5]int) as type []int in function argument

as sort.Ints expects to receive a slice []int.

Map

type Vertex struct {
    Lat, Long float64
}

var m map[string]Vertex      map declaration

func main() {
    m = make(map[string]Vertex)      instantiate a map      vs new for struct
    m["Bell Labs"] = Vertex{
        40.68433, -74.39967,
    }
    fmt.Println(m["Bell Labs"])
}
the nil map is empty and cannot be assigned to.
map literal definition
var m = map[string]Vertex{
    "Bell Labs": Vertex{
        40.68433, -74.39967,
    },
    "Google": Vertex{
        37.42202, -122.08408,
    },
}

var m = map[string]Vertex{         If the top-level type is just a type name, you can omit it from the elements of the literal.
    "Bell Labs": {40.68433, -74.39967},
    "Google":    {37.42202, -122.08408},
}
set: m[key] = elem     get: elem = m[key] Delete: delete(m, key) check: elem, ok = m[key] 
// If key is in m, ok is true. If not, ok is false and elem is the zero value for the map's element type.  Similarly, when reading from a map if the key is not present the result is the zero value for the map's element type.

String
func Fields(s string) []string      split a string by whitespace return a slice of the words

function

func add(x int, y int) int {                   //function, type after operand
    return x + y                    //When two or more consecutive named function parameters share a type, you can omit the type from all but the last.
}  
-----
as a value
hypot := func(x, y float64) float64 {
        return math.Sqrt(x*x + y*y)
    }

hypot(3, 4)

functions as closures (data type) maintain their local variable values across calls
func adder() func(int) int {
    sum := 0
    return func(x int) int {
        sum += x
        return sum
    }
}

func main() {
    pos, neg := adder(), adder()
    for i := 0; i < 10; i++ {
        fmt.Println(
            pos(i),
            neg(-2*i),
        )
    }
}

// fibonacci is a function that returns a function that returns an int.
func fibonacci() func() int {
}
Implement a fibonacci function that returns a function (a closure) that returns successive fibonacci numbers.
// fibonacci is a function that returns
// a function that returns an int.
func fibonacci() func() int {
    index := 0
    fib := func() int{
        f1 := 1
        f2 := 1
       
        for i:=0;i<index-1;i=i+1{
            temp:=f2
            f2=f1+f2
            f1=temp
        }
        index = index+1
        return f2
    }
    return fib
}

func main() {
    f := fibonacci()
    for i := 0; i < 10; i++ {
        fmt.Println(f())
    }
}



Class or method(function) on struct ******

Access Struct inside a function (binde)
type Vertex struct {   X, Y float64}        // The method receiver appears in its own argument list between the func keyword and the method name.
func (v *Vertex) Abs() float64 {    return math.Sqrt(v.X*v.X + v.Y*v.Y) }
func main() {
    v := &Vertex{3, 4}
    fmt.Println(v.Abs())
}

5 &{3 4}


 In fact, you can define a method on any type you define in your package, not just structs.
type MyFloat float64
func (f MyFloat) Abs() float64 {    if f < 0 {        return float64(-f)    }
    return float64(f)
}

func main() {
    f :=
MyFloat(-math.Sqrt2)
    fmt.Println(f.Abs())
}
 The Scale method has no effect when v is a Vertex. Scale mutates v. When v is a value (non-pointer) type, the method sees a copy of the Vertex and cannot mutate the original value.
func (v *Vertex) Scale(f float64) {
    v.X = v.X * f
    v.Y = v.Y * f
}
func (v *Vertex) Abs() float64 {    return math.Sqrt(v.X*v.X + v.Y*v.Y)}
func main() {
    v := &Vertex{3, 4}
    v.Scale(5)
    fmt.Println(v, v.Abs())
}

&{15 20} 25

Interface

 An interface type is defined by a set of methods. A value of interface type can hold any value that implements those methods.
type Abser interface {
    Abs() float64
}

func main() {
    var a Abser
    f := MyFloat(-math.Sqrt2)
    v := Vertex{3, 4}

    a = f  // a MyFloat implements Abser
    a = &v // a *Vertex implements Abser
    a = v  // a Vertex, does NOT
    // implement Abser

    fmt.Println(a.Abs())
}

type MyFloat float64

func (f MyFloat) Abs() float64 {
    if f < 0 {
        return float64(-f)
    }
    return float64(f)
}

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

type Reader interface {    Read(b []byte) (n int, err error)}
type Writer interface {    Write(b []byte) (n int, err error)}
type ReadWriter interface {     //interface embedding
    Reader
    Writer
}


Error

 An error is anything that can describe itself as an error string. The idea is captured by the predefined, built-in interface type, error, with its single method, Error, returning a string:

type error interface {
    Error() string
}
package main

import (
    "fmt"
    "time"
)

type MyError struct {
    When time.Time
    What string
}

func (e *MyError) Error() string {
    return fmt.Sprintf("at %v, %s",
        e.When, e.What)
}

func run() error {
    return &MyError{
        time.Now(),
        "it didn't work",
    }
}

func main() {
    if err := run(); err != nil {
        fmt.Println(err)
    }
}


page 55 Exercise: Errors
Http
import (
    "fmt"
    "net/http"
)

type Hello struct{}

func (h Hello) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, "Hello!")
}

func main() {
    var h Hello
    http.ListenAndServe("localhost:4000", h)
}


Threads
 

Threads

Go encourages a different approach in which shared values are passed around on channels and, in fact, never actively shared by separate threads of execution. Only one goroutine has access to the value at any given time. Data races cannot occur, by design. To encourage this way of thinking we have reduced it to a slogan:
        Do not communicate by sharing memory; instead, share memory by communicating. 

 A goroutine is a lightweight thread managed by the Go runtime.    go f(x, y, z)    starts a new goroutine running     f(x, y, z)     The evaluation of f, x, y, and z happens in the current goroutine and the execution of f happens in the new goroutine.

func say(s string) {
    for i := 0; i < 5; i++ {
        time.Sleep(100 * time.Millisecond)
        fmt.Println(s)
    }
}

func main() {
    go say("world")
    say("hello")
}    //alternate print of hello and world


Channel

 Channels are shared memory w/o need to synchronize threads.

c := make(chan int)  // Allocate a channel.
// Start the sort in a goroutine; when it completes, signal on the channel.
go func() {
    list.Sort()
    c <- 1  // Send a signal; value does not matter.
}()
doSomethingForAWhile()
<-c   // Wait for sort to finish; discard sent value.
Receivers always block until there is data to receive.

Channels are a typed conduit through which you can send and receive values with the channel operator, <-.

ch <- v    // Send v to channel ch.
v := <-ch  // Receive from ch, and assign value to v.

(The data flows in the direction of the arrow.) Like maps and slices, channels must be created before use:

ch := make(chan int)   

ci := make(chan int)            // unbuffered channel of integers
cj := make(chan int, 0)         // unbuffered channel of integers
cs := make(chan *os.File, 100)  // buffered channel of pointers to Files

Incoming chan string
Outgoing chan string

By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables.

package main
import "fmt"
func sum(a []int, c chan int) {
    sum := 0
    for _, v := range a {
        sum += v
    }
    c <- sum // send sum to c
}

func main() {
    a := []int{7, 2, 8, -9, 4, 0}

    c := make(chan int)
    go sum(a[:len(a)/2], c)
    go sum(a[len(a)/2:], c)
    x, y := <-c, <-c // receive from c

    fmt.Println(x, y, x+y)
}
 Channels can be buffered. Provide the buffer length as the second argument to make to initialize a buffered channel:
ch := make(chan int, 100)
Sends to a buffered channel block only when the buffer is full. Receives block when the buffer is empty.Modify the example to overfill the buffer and see what happens.
package main

import "fmt"

func main() {
    c := make(chan int, 1)
    c <- 1
    c <- 2
    fmt.Println(<-c)
    fmt.Println(<-c)
}

Select

like switch statement but cases are communication operations. it blocks until one of the cases succeeds and in that case performs the case task.

select {                                  
    case result := <-c:                // a new message received
           fmt.Print(result)            
    case <-timeout:                    //time out signal received
           fmt.Print("Timed out\n")
           return                         
}
   //waits until either the next result is ready or the timeout occurs



HTTP

package http type Handler interface { ServeHTTP(w ResponseWriter, r *Request) }

In the following example, the type Hello implements http.Handler

go to http://localhost:4000/  to see Hello!
import (
    "fmt"
    "net/http"
)

type Hello struct{}

func (h Hello) ServeHTTP(
    w http.ResponseWriter,
    r *http.Request) {
    fmt.Fprint(w, "Hello!")
}

func main() {
    var h Hello
    http.ListenAndServe("localhost:4000", h)
}


Other topics

defer: schedules a function call (the deferred function) to be run immediately before the function executing the defer returns. It's an unusual but effective way to deal with situations such as resources that must be released regardless of which path a function takes to return. The canonical examples are unlocking a mutex or closing a file.
...//parent funciton body
defer func(v string) {
      fmt.Printf(v)
    }(fruit)
...

Triple Dots

The signature of Printf uses the type ...interface{} for its final argument to specify that an arbitrary number of parameters (of arbitrary type) can appear after the format.

func Printf(format string, v ...interface{}) (n int, err error) {

Within the function Printf, v acts like a variable of type []interface{} but if it is passed to another variadic function, it acts like a regular list of arguments. Here is the implementation of the function log.Println we used above. It passes its arguments directly to fmt.Sprintln for the actual formatting.

// Println prints to the standard logger in the manner of fmt.Println.
func Println(v ...interface{}) {
    std.Output(2, fmt.Sprintln(v...))  // Output takes parameters (int, string)
}

We write ... after v in the nested call to Sprintln to tell the compiler to treat v as a list of arguments; otherwise it would just pass v as a single slice argument.

There's even more to printing than we've covered here. See the godoc documentation for package fmt for the details.

By the way, a ... parameter can be of a specific type, for instance ...int for a min function that chooses the least of a list of integers:

func Min(a ...int) int {
    min := int(^uint(0) >> 1)  // largest int
    for _, i := range a {
        if i < min {
            min = i
        }
    }
    return min
}


NET

package main

import (
    "io"
    "log"
    "net"
)

func main() {
    // Listen on TCP port 2000 on all interfaces.
    l, err := net.Listen("tcp", ":2000")
    if err != nil {
        log.Fatal(err)
    }
    for {
        // Wait for a connection.
        conn, err := l.Accept()
        if err != nil {
            log.Fatal(err)
        }
        // Handle the connection in a new goroutine.
        // The loop then returns to accepting, so that
        // multiple connections may be served concurrently.
        go func(c net.Conn) {
            // Echo all incoming data.
            io.Copy(c, c)
            // Shut down the connection.
            c.Close()
        }(conn)
    }
}


=====================================================================

Subpages (1): Other Issues
Comments