go programming language (golang)

40
TECH-TALK Ishin Vin Go Programming Language [email protected]

Upload: ishin-vin

Post on 22-Jan-2018

298 views

Category:

Education


7 download

TRANSCRIPT

TECH-TALK

Ishin Vin

Go Programming Language

[email protected]

Contents

• Introduction

• Why Go?

• Important note

• Basic commands

• Basic Syntax

• net/http package

Introduction

Go is initially developed at Google in 2007.

Go was announced in November 2009 and is used in some of the Google’s production systems.

Go is an open source programming language.

Go 1 was released in March 2012

Currently, Go 1.8 released in 16 February 2017

Go is a general-purpose language.

Go is statically typed, compiled language.

Why Go?

Go is an open-source but backed up by a large corporation.

Automatic memory management (garbage collection).

Strong focus on support for concurrency.

Fast compilation and execution

Statically type, but feels like dynamically typed

Good cross-platform support

Go compiles to native machine code

Rapid development and growing community

Used by big companies (Google, Dropbox, Docker, Cloudflare, Soundcloud)

Important note

No type inheritance

No method or operator overloading

No support for pointer arithmetic

No support for Assertions

No Exceptions - instead use an error return type

No Generics support

Too much Boilerplate (codes that have to be included in many places with little or no alteration)

Bad dependency management

Go uses URL based dependency imports

go get http://github.com/somename/somelibrary

import github.com/somename/somelibrary

Basic commandsgo is a tool for managing Go source code.

Usage:

go command [arguments]

The commands are:

build compile packages and dependencies

clean remove object files

doc show documentation for package or symbol

env print Go environment information

get download and install packages and dependencies

install compile and install packages and dependencies

run compile and run Go program

test test packages

version print Go version

Use "go help [command]" for more information about a command.

Basic Syntax

package main

import "fmt”

func main() {

fmt.Println("Hello, 世界")

}

Output: Hello, 世界

Go keywords

default

defer

else

fallthrough

for

Go has only 25 keywords, even less than English alphabet!

break

case

chan

const

continue

func

go

goto

if

import

interface

map

package

range

return

select

struct

switch

type

var

Basic types

bool

string

int int8 int16 int32 int64

uint uint8 uint16 uint32 uint64 uintptr

byte // alias for uint8

rune // alias for int32

float32 float64

complex64 complex128

Packages

Every Go program is made up of package.

Program start running in package main.

Name is exported if it begins with a capital letter.

package main

import (

“fmt”

“math”

)

func main () {

fmt.Println(math.pi) //error

fmt.Println(math.Pi)

}

Functions// type comes after the variable name

func add(x int, y int) int {

return x + y

}

// when arguments share the same type, type can be omitted but the last

func add(x, y int) int {

return x + y

}

func swap(x, y string) (string, string) {

return y, x // return multiple values

}

func hello(x, y string) (a, b string) {

a = x

b = y

return // name return value or naked return

}

Variables

// variables with initializers

var i, j int = 1, 2

var c, golang, java = false, true, “no!”

var c, golang, java bool

func main() {

var i int

}

Use var statement declare a list of variables.

Inside a functions, the := short assignment can be use in place of var

func main() {

c, golang, java := false, true, “no!”

}

Zero values

var i int

var f float64

var b bool

var s string

fmt.Printf(“%v %v %v %q\n”, i, f, b, s)

// output: 0 0 false “”

Variables declared without initial value are given their zero values.

0 for numeric types

false for boolean type

“” for string type

Type conversion

// Go assignment between items of different type requires an explicit conversion

var i int = 42

var f float64 = float64(i)

var u unit = unit(f)

Constants

// Constants are declared like variables, but with the const keyword

const Pi = 3.14

For

sum := 0

for i := 0; i < 10; i++ {

sum += i

}

// note: no () surrounding the three components; {} always required

Go has only one looping construct, the for loop.

For is Go’s while

sum := 1

for sum < 1000 {

sum += sum

}

If else

if x := math.Sqrt(100); x < 10 {

fmt.Printf(“Square root of 100 is %v\n”, x)

} else {

fmt.Printf(“Square root of 100 is %v\n”, x)

}

// note: no () surrounding the condition; {} always required

If can start with a short statement to execute before condition.

Switch

package main

import (

"fmt”

"runtime”

)

func main() {

switch os := runtime.GOOS; os {

case "darwin":

fmt.Println(" Go runs on OS X.”)

case "linux":

fmt.Println(" Go runs on Linux.”)

default:

fmt.Printf(" Go runs on %s.", os)

}

}

Switch can start with a short statement to execute before condition.

Defer

func main() {

fmt.Println("counting down”)

defer fmt.Print(”\ndone”)

for i := 0; i < 10; i++ {

defer fmt.Print(i, “ ”)

}

}

// output:

counting down

9 8 7 6 5 4 3 2 1 0

done

Defers the execution of a function until the surrounding function returns

Pointer

i := 21

p := &i // store address of i in pointer variable p

fmt.Printf(“Address stored in p variable: %p\n”, p) // print address

fmt.Printf(“Value of i is: %v\n”, *p) // read i through the pointer

*p = 77 // set i through the pointer

fmt.Printf(“New value of i is: %v\n”, i) // see the new value of i

Pointer is a variable whose value is the address of another variable.

Ampersand (&) operator denotes an address in memory.

Asterisk (*) operator denotes the pointer's underlying value.

Output:

Address stored in p variable: 0x1040e0f8

Value of i is: 21

New value of i is: 77

Struct

type Vertex struct {

X int

Y int

}

func main() {

v := Vertex{1, 2}

p := &v

p.X = 1e9

fmt.Println(v)

}

// output: {1000000000 2}

Struct is a collection of fields

Struct fields are accessed using a dot

Struct fields can be accessed through a struct pointer

Arrays & Slicesvar a [10]int

Array has a fixed size.

Slice is a dynamically-size, flexible view of an array; var a []int

primes := [6]int{2, 3, 5, 7, 11, 13}

var s []int = primes[1:4]

fmt.Println(s)

// output: [3 5 7]

Slice is like reference to array; it does not store any data.

names := [4]string{“Jonh”, “Paul”, “George”, “Ringo”}

fmt.Println(names) // [John Paul George Ringo]

a := names[1:3]

fmt.Println(a) // [Paul George]

a[0] = "XXX”

fmt.Println(a) // [XXX George]

fmt.Println(names) // [John XXX George Ringo]

Make function

func printSlice(s string, x []int) {

fmt.Printf("%s len=%d cap=%d %v\n", s, len(x), cap(x), x)

}

func main() {

a := make([]int, 5) // len(a) = 5; length of a is 5

printSlice("a", a) // output: a len=5 cap=5 [0 0 0 0 0]

b := make([]int, 0, 5) // len(b) = 0, cap(b) = 5

printSlice("b", b) // output: b len=0 cap=5 []

}

Slices can be created with the built-in make function; this is how you create dynamically-sized array.

Append function

Go provides a built-in append function

func main() {

var s []int

printSlice(s) // output: len=0 cap=0 []

s = append(s, 0) // append works on nil slices.

printSlice(s) // output: len=1 cap=2 [0]

s = append(s, 1) // The slice grows as needed.

printSlice(s) // output: len=2 cap=2 [0 1]

s = append(s, 2, 3, 4) // add more than one element at a time

printSlice(s) // output: len=5 cap=8 [0 1 2 3 4]

}

func printSlice(s []int) {

fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)

}

Range

Range form the for loop iterates over a slice or map

var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}

for i, v := range pow {

fmt.Printf("2^%d = %d\n", i, v)

}

// output:

2^0 = 1

2^1 = 2

2^2 = 4

2^3 = 8

2^4 = 16

2^5 = 32

2^6 = 64

2^7 = 128

Mapmake function returns a map of the given type, initialized and ready to use

m := make(map[string]int) // initialized map

m["Answer"] = 42 // insert element

fmt.Println("The value:", m["Answer"]) // output: The value: 42

m["Answer"] = 48 // update element

fmt.Println("The value:", m["Answer"]) //output: The value: 48

delete(m, "Answer”) // delete element

fmt.Println("The value:", m["Answer"]) //output: The value: 0

v, ok := m["Answer”] // If key is in map, ok is true

fmt.Println("The value:", v, "Present?", ok) // If not, ok is false

// output: The value: 0 Present? false

Function closuresClosure is a function value that references variable from outside its body

func adder() func(int) int {

sum := 0

return func(x int) int {

sum += x

return sum

}

}

func main() {

pos := adder()

for i := 0; i<5; i++ {

fmt.Print(pos(i), “ ”)

}

}

// output: 0 1 3 6 10

Methods

A method is a function with a special receiver argument.

type MyFloat float64

func (f MyFloat) Abs() float64 {

if f < 0 {

return float64(-f)

}

return float64(f)

}

func main() {

f := MyFloat(-21)

fmt.Println(f.Abs())

}

// output: 21

Receiver type must be defined in the same package as the method.

Pointer receiversMethods with pointer receivers can modify the value to which the receiver points

type Vertex struct {

X, Y float64

}

func (v Vertex) Abs() float64 {

return math.Sqrt(v.X*v.X + v.Y*v.Y)

}

func (v *Vertex) Scale(f float64) {

v.X = v.X * f

v.Y = v.Y * f

}

func main() {

v := Vertex{3, 4}

fmt.Println(v.Abs()) // output: 5

v.Scale(10)

fmt.Println(v.Abs()) // output: 50

}

Interface

type I interface {

M()

}

type T struct {

S string

}

func (t T) M() { // This method means type T implements the interface I

fmt.Println(t.S)

}

func main() {

var i I = T{"hello”}

i.M() // output: hello

}

Interface type is defined as a set of method signatures.

A type implements an interface by implementing its methods.

There is no explicit declaration of intent, no "implements" keyword.

Empty interface

func main() {

var i interface{}

describe(i) // output: (<nil>, <nil>)

i = 42

describe(i) // output: (42, int)

i = "hello"

describe(i) // output: (hello, string)

}

func describe(i interface{}) {

fmt.Printf("(%v, %T)\n", i, i)

}

Interface type that specifies zero methods is known as the empty interface

An empty interface may hold values of any type.

Ex: fmt.Print takes any number of arguments of type interface{}

Stringer

type Person struct {

Name string

Age int

}

func (p Person) String() string {

return fmt.Sprintf("%v (%v years)", p.Name, p.Age)

}

func main() {

a := Person{"Arthur Dent", 42}

fmt.Println(a) // output: Arthur Dent (42 years)

}

Stringer is defined by the fmt package

type Stringer interface {

String() string

}

Stringer is a type that can describe itself as a string

fmt package (and many others) look for this interface to print values

Error

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) // at 2017-03-08 23:00:00 +0700 ICT, it didn't work

}

}

The error type is a built-in interface similar to fmt.Stringer

type error interface {

Error() string

}

ReaderThe io package specifies the io.Reader interface, which represents the read end of a stream of data.

func main() {

r := strings.NewReader("Hello, Reader!”)

b := make([]byte, 8)

for {

n, err := r.Read(b)

if err == io.EOF {

break

}

fmt.Printf("n = %v err = %v b = %v\n", n, err, b)

fmt.Printf("b[:n] = %q\n", b[:n])

}

}

func (T) Read(b []byte) (n int, err error)

Goroutine

Goroutines run in the same address space, so access to shared memory must be synchronized.

One goroutine usually uses 4 - 5 KB of stack memory.

Therefore, it's not hard to run thousands of goroutines on a single computer.

Goroutine is a lightweight thread managed by the Go runtime.

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")

}

// output:

world

hello

hello

world

world

hello

hello

world

world

hello

Channel

Channel is one of the features that make Golang unique.

The purpose of using Channel is to transfer values in goroutines.

ch <- v // Send v to channel ch.

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

Like maps and slices, channels must be created before use:

ch := make(chan int)

Channel: exampleSum the numbers in a slice, distributing the work between two goroutines.

func sum(s []int, c chan int) {

sum := 0

for _, v := range s {

sum += v

}

c <- sum // send sum to c

}

func main() {

s := []int{7, 2, 8, -9, 4, 0}

c := make(chan int)

go sum(s[:len(s)/2], c) // [7 2 8]

go sum(s[len(s)/2:], c) // [-9 4 0]

x, y := <-c, <-c // receive from c

fmt.Println(x, y, x+y) //output: -5 17 12

}

Once both goroutines completed their computation, it calculates the final result.

SelectSelect statement lets a goroutine wait on multiple communication operations.

A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.

func main() {

tick := time.Tick(100 * time.Millisecond)

boom := time.After(500 * time.Millisecond)

for {

select {

case <-tick:

fmt.Println("tick.")

case <-boom:

fmt.Println("BOOM!")

return

}

}

}

// output:

tick.

tick.

tick.

tick.

tick.

BOOM!

net/http packagePackage http provides HTTP client and server implementations.

More reader : https://golang.org/pkg/net/http/

func HandleFunc : registers the handler function for the given pattern in the DefaultServeMux. Example : http.HandleFunc("/", hello)

func ListenAndServe : listens on the TCP network address and then calls Serve with handler to handle requests on incoming connections. Accepted connections are configured to enable TCP keep-alives.

Example : http.ListenAndServe(":8080", nil)

package main

import (

"fmt"

"net/http"

)

func hello(w http.ResponseWriter, r *http.Request) {

fmt.Fprintf(w, "Hello world!")

}

func main() {

http.HandleFunc("/", hello)

http.ListenAndServe(":8080", nil)

}

References

1. https://golang.org

2. https://tour.golang.org

3. https://en.wikipedia.org/wiki/Go_(programming_language)

4. https://www.gitbook.com/book/astaxie/build-web-application-with-golang

Sample code : https://github.com/shin7/go-rest-api

Thank You!