Golang: Undertanding Basic of Concurrence Programming in the easiest way

In this blog post I’m gonna show you an easy example regarding basic concurrency in Golang programming, it will be an easy step-by-step approach to avoid misapprehend to the example (sample).

What is concurrency?

Concurrency is the composition of independently executing computations.

Concurrency is a way to structure software, particularly as a way to write clean code that interacts well with the real world.

It is not parallelism.

Rob Pike, Google

https://talks.golang.org/2012/concurrency.slide#6

Step 1:

package main

import (
	"fmt"
	"time"
)

func sayHello() {
	for x := 0; x < 10; x++ {
		fmt.Println("Hello ", x)
	}
}

func main() {
	start := time.Now()
	fmt.Println("Start at: ", start)
	fmt.Println("------------------------------------------------------")

	go sayHello()

	fmt.Println("------------------------------------------------------")
	fmt.Println("End at: ", time.Now())
	fmt.Println("Done at: ", time.Now().Sub(start))
}

Output:

basic1

In this  step we do not have output to be printed on the screen from sayHello() because the main process ends before the goroutine being executed. Golang program execution begins by initializing the main package and then invoking the function main. When the function main returns, the program exits. It does not wait for other (non-main) goroutines to complete.

A goroutine is a lightweight thread managed by the Go runtime.

Step 2

func main() {
	start := time.Now()
	fmt.Println("Start at: ", start)
	fmt.Println("------------------------------------------------------")

	go sayHello()

	time.Sleep(time.Second)

	fmt.Println("------------------------------------------------------")
	fmt.Println("End at: ", time.Now())
	fmt.Println("Done at: ", time.Now().Sub(start))
}

Output:

Basic2delay

The example above uses delay to make main function (process) waits the goroutine through 1 second before ends, 1 second is more than enough for Golang to print out all the lines on the screen. for the next step I’m gonna add  delay to the loop inside the sayHello() function so it will takes 9 seconds to be finished (and keep 1 second delay in the main function), let’s see what will take place.

Step 3

func sayHello() {
	for x := 0; x < 10; x++ {
		fmt.Println("Hello ", x)
		time.Sleep(time.Second)
	}
}

func main() {
	start := time.Now()
	fmt.Println("Start at: ", start)
	fmt.Println("------------------------------------------------------")

	go sayHello()

	time.Sleep(time.Second)

	fmt.Println("------------------------------------------------------")
	fmt.Println("End at: ", time.Now())
	fmt.Println("Done at: ", time.Now().Sub(start))
}

Output:

Basic3

Each loop waits for 1 second after printed the text, so in 1 minute it adequate to print 2 lines.

Step 4 Make main function wait goroutine to be done before it ends

We can make main function to wait all goroutines to be done before end it’s process without using primitive delay (time.Sleep(time.Second)) function.

package main

import (
	"fmt"
	"time"
	"sync"
)

func sayHello(wg *sync.WaitGroup) {
	for x := 0; x < 10; x++ {
		fmt.Println("Hello ", x)
		time.Sleep(time.Second)

		if x == 8 {
			wg.Done()
		}

	}
}

func main() {
	var wg sync.WaitGroup

	start := time.Now()
	fmt.Println("Start at: ", start)
	fmt.Println("------------------------------------------------------")

	wg.Add(1)
	go sayHello(&wg)

	wg.Wait()

	fmt.Println("------------------------------------------------------")
	fmt.Println("End at: ", time.Now())
	fmt.Println("Done at: ", time.Now().Sub(start))
}

Output:

basic5

Please pay attention to these lines:

var wg sync.WaitGroup
wg.Add(1) // Should be called before goroutine call
wg.Done()
wg.Wait()

Step 5 Go channel

Channels are the pipes that connect concurrent goroutines. You can send values into channels from one goroutine (ch<-) and receive those values into another goroutine (<-ch).

I don’t want to talk much about channel to avoid confusion, instead I will just show you several behavior of channel.

Receive operation <-ch in the main

package main

import (
	"fmt"
)

func sayHello(msg chan string) {

	msg <- "Hello Lorem ipsum1!"
	msg <- "Hello Lorem ipsum2!"
	msg <- "Hello Lorem ipsum3!"
	close(msg)
}

func main() {
	msg := make(chan string)

	go sayHello(msg)

	for value := range(msg) {
		fmt.Println(value);
	}

	// Or you could just uncomment following lines (but comments 'for' lines first)
	// fmt.Println("1:", <-msg)
	// fmt.Println("2:", <-msg)
	// fmt.Println("3:", <-msg)
	// fmt.Println("4:", <-msg) // empty or error if you did't close(msg)
}

Output:

channelx1

package main

import (
      "fmt"
)

func sayHello(msg chan string) {
      says := "Says: "
      for x := 0; x < 10; x++ {
          says += fmt.Sprintf("Hello-%d ,", x)
          fmt.Println("ok")
      }   

      msg <- says
}

func main() {
      msg := make(chan string)
      go sayHello(msg)
      fmt.Println(<-msg)
}

Output:

channel1

Receive operation (<-msg) in main() is a blocking operation, so the program won’t continue until a value is available.

Receive operation <-ch from goroutine to be printed by function

package main

import (
	"fmt"
)

func sayHello(msg chan string) {

	msg <- "hello world"

}

func printHello2(msg string) {
	fmt.Println(msg)

}

func main() {

	msg := make(chan string)

	go sayHello(msg)

	printHello2(<-msg)

}

Output:

exited1

Select

package main

import (
	"fmt"
	"time"
)

func main() {

	// For our example we'll select across two channels.
	c1 := make(chan string)
	c2 := make(chan string)

	go func() {
		time.Sleep(time.Second * 1)
		c1 <- "one"
	}()

	go func() {
		time.Sleep(time.Second * 2)
		c2 <- "two"
	}()

	for {

		select {
		case msg1, ok := <-c1:
			if ok {
				fmt.Println("received", msg1)
			}
		case msg2, ok := <-c2:
			if ok {
				fmt.Println("received", msg2)
			}
		case <-time.After(3000 * time.Millisecond):
			fmt.Printf("Timed out!")
			return
		}

	}
}

Output:

timeout

The select 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.

Advertisements

Golang: Debuging Go code

In this post I will show you some easy (tricky) ways to debug go code (forget about gdb, it’s too hard to understand).

Print Struct as string

package main

import (
    "fmt"
)

type Person struct {
    Name, Address       string
    Age, Height, Weight int
}

func main() {
    Yusuf := Person{
        Name:    "Yoesoff",
        Address: "Bandung Barat",
        Age:     17,
        Height:  165,
        Weight:  70,
    }   

    fmt.Println(Yusuf) // Print struct as string
}

Output:

{Yoesoff Bandung Barat 17 165 70}
{Yoesoff Bandung Barat 17 165 70}

Use fmt.Printf to find Variable / Object type in Golang

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

import (
    "fmt"
)

type Person struct {
    Name, Address       string
    Age, Height, Weight int
}

func main() {
    Yusuf := Person{
        Name:    "Yoesoff",
        Address: "Bandung Barat",
        Age:     17,
        Height:  165,
        Weight:  70,
    }   

     fmt.Printf("%T\n", A)
     fmt.Printf("%T\n", B)
     fmt.Printf("%T\n", Yusuf)
}

Output:

string
int
main.Person

Use reflect to find Variable / Object type in Golang

package main

import (
	"fmt"
	"reflect"
)

type Person struct {
	Name, Address       string
	Age, Height, Weight int
}

func main() {
	Yusuf := Person{
		Name:    "Yoesoff",
		Address: "Bandung Barat",
		Age:     17,
		Height:  165,
		Weight:  70,
	}

	Yuka := &Person{
		"Zha",
		"Bandung Barat",
		16,
		165,
		60,
	}

	A := 10
	B := 12
	C := A + B
	D := "I AM A BATMAN"

	fmt.Println(reflect.TypeOf(Yusuf))
	fmt.Println(reflect.TypeOf(Yuka))
	fmt.Println(reflect.TypeOf(*Yuka))
	fmt.Println(reflect.TypeOf(C))
	fmt.Println(reflect.TypeOf(D))
}

Output:

main.Person
*main.Person
main.Person
int
string

Using go-spew to debug Go data structures (Object and Variable)

Installation

$ go get -u github.com/davecgh/go-spew/spew

  package main

  import (
      "github.com/davecgh/go-spew/spew"
  )

  type Person struct {
      Name, Address       string
      Age, Height, Weight int
  }

  func main() {
      Yusuf := Person{
          Name:    "Yoesoff",
          Address: "Bandung Barat",
          Age:     17,
          Height:  165,
          Weight:  70,
      }

      A := 10
      B := 12
      C := A + B
      D := "Wakwau Golang si Golang"

      spew.Dump(Yusuf)
      spew.Dump(C)
      spew.Dump(D)
  }

Output:

(main.Person) {
Name: (string) (len=7) “Yoesoff”,
Address: (string) (len=13) “Bandung Barat”,
Age: (int) 17,
Height: (int) 165,
Weight: (int) 70
}
(int) 22

(string) (len=23) “Wakwau Golang si Golang”

Using godebug A cross-platform debugger for Go.

Installation:

$ go get github.com/mailgun/godebug

1. install-godebug

Setup Go executable binary path :

2. Setup Go Binari

3. Go-Debug-Running

Insert a breakpoint anywhere in a source file you want to debug:

_ = "breakpoint"

package main

  import "fmt"

  type Person struct {
      Name, Address       string
      Age, Height, Weight int
  }

  func main() {
      Yusuf := Person{
          Name:    "Yoesoff",
          Address: "Bandung Barat",
          Age:     17,
          Height:  165,
          Weight:  70,
      }

      _ = "breakpoint"

      A := 10
      B := 12
      C := A + B
      D := "Wakwau Golang si Golang"
      _ = "breakpoint"

      fmt.Println(A)
      fmt.Println(B)
      fmt.Println(C)
      fmt.Println(D)
      fmt.Println(Yusuf)
  }

Output:

6.Godebugx

Golang: Simple Golang Web Application

In this post I’d like to show you a simple web application developed using Go / Golang that demonstrate you several basic web  functionalities such as http request and http response.

The result should be something like this that runs in your web browser:

golang-x1golang-x2

main.go

package main

  import (
      "fmt"
      "html/template"
      "net/http"
      "os"
  )

  type FormData struct {
      Name    string
      Country string
  }

  func form(w http.ResponseWriter, r *http.Request) {
      folderpath, _ := os.Getwd() // Get current folder location
      form, _ := template.ParseFiles(folderpath + "/form.gtpl")
      form.Execute(w, nil)
  }

  func view(w http.ResponseWriter, r *http.Request) {
      if r.Method == "POST" {

          // Process form data
          r.ParseForm()
          name := r.Form["name"][0] // Yes, Go able to receive more than one name
          country := r.Form["country"][0]
          //fmt.Println(name)
          //fmt.Println(country)

          data := FormData{
              Name:    name,
              Country: country,
          }   

          folderpath, _ := os.Getwd() // Get current folder location
          view, _ := template.ParseFiles(folderpath + "/view.gtpl")
          view.Execute(w, data)
      } else {
         fmt.Fprintf(w, "Method not allowed!") // write data to response
      }
  }

  func main() {
      // Routes
      http.HandleFunc("/", form)
      http.HandleFunc("/view", view)

      http.ListenAndServe(":8000", nil) // setting listening port
  }

form.gtpl

<html>

      <body>
<h1>Hallo World</h1>
<form method="POST" action="/view">
              Name : <input name="name" />
              Coutry : <input name="country" />

              <input type="submit" />
          </form>

      </body>

  </html>

view.gtpl

 <html>
  <head>
  <title></title>
  </head>
      <body>
          Hello World 

          Welcome -{{.Name}}- from -{{.Country}}-
      </body>
  </html>

Build and Run The code

golang x3

Code Snapshot

VIMX1VIMX2VIMX3

Golang: error while open gtpl / html template

Today I just started my Golang web self training, I train my self a basic stuff regarding Golang web programming, I just got an issue that wasted my time for about 2 hours, a little bit frustrating for me because I’m sure I have followed the instruction in the right way, I type the code by my self then delete all of it and replace it by pasted code from the tutorial (the tutorial is here) but still got the same errors again and again:

This is the error that I got recently


2017/04/02 21:26:21 http: panic serving 127.0.0.1:40336: runtime error: invalid memory address or nil pointer dereference
goroutine 8 [running]:
net/http.(*conn).serve.func1(0xc4200da780)
 /usr/local/go/src/net/http/server.go:1491 +0x12a
panic(0x6d5ca0, 0xc42000c150)
 /usr/local/go/src/runtime/panic.go:458 +0x243
html/template.(*Template).escape(0x0, 0x0, 0x0)
 /usr/local/go/src/html/template/template.go:79 +0x44
html/template.(*Template).Execute(0x0, 0x8835c0, 0xc4201500d0, 0x0, 0x0, 0xc420140210, 0xc4201420e0)
 /usr/local/go/src/html/template/template.go:101 +0x2f
main.login(0x886fc0, 0xc4201500d0, 0xc4201083c0)
 /home/yusuf/go-learn2/src/web/main.go:29 +0x4a9
net/http.HandlerFunc.ServeHTTP(0x7546f8, 0x886fc0, 0xc4201500d0, 0xc4201083c0)
 /usr/local/go/src/net/http/server.go:1726 +0x44
net/http.(*ServeMux).ServeHTTP(0x8a6dc0, 0x886fc0, 0xc4201500d0, 0xc4201083c0)
 /usr/local/go/src/net/http/server.go:2022 +0x7f
net/http.serverHandler.ServeHTTP(0xc4200da200, 0x886fc0, 0xc4201500d0, 0xc4201083c0)
 /usr/local/go/src/net/http/server.go:2202 +0x7d
net/http.(*conn).serve(0xc4200da780, 0x887600, 0xc420016e40)
 /usr/local/go/src/net/http/server.go:1579 +0x4b7
created by net/http.(*Server).Serve
 /usr/local/go/src/net/http/server.go:2293 +0x44d

 

 

Weird error, but fortunately after 2 hours wasting of time I realize that the error is telling me about something wrong at following line:


/home/yusuf/go-learn2/src/web/main.go:29 +0x4a9

the code that contain a command to read the go template file ( login.gtpl ), the code is :


t, _ := template.ParseFiles("login.gtpl")
 t.Execute(w, nil)

then I replaced the path of file to the full path and then the code is working:


t, _ := template.ParseFiles("/my/full/path/login.gtpl")
t.Execute(w, nil)

and after that I set the code back to previous condition


t, _ := template.ParseFiles("login.gtpl")
t.Execute(w, nil)

 

and the code is still working, I don’t know why but it’s working now even without fullpath.

*if you still got an error regarding this file reader you could just give full access to the file using command below:

</pre>
sudo chmod 777 /my/full/path/login.gtpl

Golang: Catatan belajar OOP dengan GO language

Source code di sini

Struct pada Golang adalah kumpulan dari fields dan atau properties. Struct berbeda dengan Class pada Java misalnya, karena salah satunya Struct pada Go menggunakan Composition bukan inheritance yaitu dengan meng-compose sebuah struct di struct lainnya sehingga fields dan atau properties dari sebuat struct ada di dalam struct lain yang meng-embed struct tersebut.

Composition atau juga bisa di sebut embedding bisa dikatakan sebagai pengganti penggunaan inheritance di GO ,  untuk menjadikan gambaran yang lebih jelas saya mencoba mempraktekan perilaku tersebut dalam beberapa baris bahasa GO di bawah ini, selain Composition/embedding disini juga terdapat penggunaan interface sederhana, berikut kodenya:


package main

import (
	f "fmt"
	s "strconv"
)

// 1. Manusia pada umumnya
type Manusia struct {
	nama                     string
	umur                     int
	telepon, hanphone, email string
}

// 2. Manusia berstatus Mahasiswa
type Mahasiswa struct {
	Manusia       // Embed Manusia / semacam extend di OOP Java
	kampus, kosan string
	uang_jajan    float32
}

// 3. Mahasiswa berstatus Karyawan
type Karyawan struct {
	Manusia            // Embed Manusia / semacam extend di OOP Java
	perusahaan, asrama string
	salary             float32
}

// Semua manusia pasti makan
func (m Manusia) makan(makanan string) {
	f.Printf("Makan: %s \n", makanan)
}

// Semua manusia pasti minum
func (m Manusia) minum(minuman string) {
	f.Printf("Minum: %s \n", minuman)
}

// Semua mahasiswa pasti ujian
func (m Mahasiswa) ujian(mata_kuliah string) {
	f.Printf("Ujian mata kuliah: %s \n", mata_kuliah)
}

// Semua karyawan pasti gajian
func (k Karyawan) gajian() {
	f.Printf("Gajian: $.%e ", k.salary)
}

// Interfaces untuk yang pelajar
type Pelajar interface {
	makan(makanan string)
	minum(minuman string)
	ujian(mata_kuliah string)
}

type Pekerja interface {
	makan(makanan string)
	minum(minuman string)
	gajian()
}

// Fungsi Di luar interface / ga ada di interface
func (m *Manusia) bikinHoax() {
	f.Printf(m.nama + " Bikin berita Hoax biar kacau...... ")
}

// Main function
func main() {
	f.Println(`بِسْــــــــــــــــــمِ اللهِ الرَّحْمَنِ الرَّحِيْمِ`)

	// Implementasi Struct di atas adalah sebagai berikut

	// 1. Mahasiswa
	joni := Mahasiswa{Manusia{"Joni", 20, "0214353454", "098342342", "jonni@example.com"}, "Prapatan University", "Kosan ibu Nuri", 200}
	var joni_mahasiswa Pelajar // Interface
	f.Println(`Nama:` + joni.nama)
	f.Println(`Nama:` + s.Itoa(joni.umur))
	f.Println(`Nama:` + joni.telepon)
	f.Println(`Nama:` + joni.hanphone)
	f.Println(`Nama:` + joni.email)

	joni_mahasiswa = joni
	joni_mahasiswa.makan(`Nasi padang`)
	joni_mahasiswa.minum(`Es Campur`)
	joni_mahasiswa.ujian(`Sastra Rusia`)
	// Kalo tidak di komen fungsi di bawah akan ada error: joni_mahasiswa.bikinHoax undefined (type Pelajar has no field or method bikinHoax)
	// joni_mahasiswa.bikinHoax() // Ya iya lah masa Mahasiswa bikin Hoax, bego di piara mah ga usah kuliah...
	joni.bikinHoax() //Joni sebagai manusia bisa khilaf, jadi ini akan jalan

	f.Println(``)
	f.Println(`------------------------`)
	f.Println(``)

	// 2. Karyawan
	kokom := Karyawan{Manusia{"Kokom Komariyah", 27, "02199999", "0888902343", "kokok-cute@example.com"}, "PT. Telekokom Tbbek", "Rumah dinas Telekokom", 20000}
	var kokom_karyawan Pekerja // Interface
	f.Println(`Nama:` + kokom.nama)
	f.Println(`Nama:` + s.Itoa(kokom.umur))
	f.Println(`Nama:` + kokom.telepon)
	f.Println(`Nama:` + kokom.hanphone)
	f.Println(`Nama:` + kokom.email)

	kokom_karyawan = kokom
	kokom_karyawan.makan(`Steak Kerbau Buleng`)
	kokom_karyawan.minum(`Vodka Bridenk`)
	kokom_karyawan.gajian()
	f.Println(``)
	// Kalo tidak di komen fungsi di bawah akan ada error: kokom_karyawan.bikinHoax undefined (type Pelajar has no field or method bikinHoax)
	// kokom_karyawan.bikinHoax() // masa Professional bikin Hoax...
	kokom.bikinHoax() //Kokom sebagai manusia bisa khilaf, jadi ini jalan
	f.Println(``)
	f.Println(`----------------------------
	f.Println(``)
	// Manusia biasa
	manusia := Manusia{"Entahlah", 27, "02100", "08000", "teuing@ex.com"}
	f.Println(`Nama:` + manusia.nama)
	f.Println(`Nama:` + s.Itoa(manusia.umur))
	f.Println(`Nama:` + manusia.telepon)
	f.Println(`Nama:` + manusia.hanphone)
	f.Println(`Nama:` + manusia.email)
	manusia.bikinHoax() // Wajar namanya manusia
}

Golang: GPM ERROR: Failed to compile. Check the logs

I got following error during go 1.8 installation using GVM ( Golang Version Manager) :

yusuf@yusuf-he:~/htdocs/xxx*$ gvm install go1.8
Downloading Go source…
Installing go1.8…
* Compiling…
ERROR: Failed to compile. Check the logs at /home/yusuf/.gvm/logs/go-go1.8-compile.log
ERROR: Failed to use installed version

My current system go version is:

go version go1.7.3 linux/amd64

and my OS is:

No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 14.04.5 LTS
Release: 14.04
Codename: trusty

Solution that proven to work on my machine above was by following the instruction at the following url

gvm install go1.4 
gvm use go1.4 
export GOROOT_BOOTSTRAP=$GOROOT 
gvm install go1.5   (or another higher go version)

The reason why the error happened

You will need go1.4 installed before you can install go1.5 (since this is compiling from go source and 1.5 doesnt use C anymore) run gvm install go1.4 gvm use go1.4 export GOROOT_BOOTSTRAP=$GOROOTthen run gvm install go1.5 . This should be fixed in pull #154

 

 

CIMB Niaga Transfer Ke Rekening Ponsel Error / Gagal

Tempat latihan olahraga  Beladiri Kickboxing, Sanda dan Muaythai : KBI Bandung

Seingat saya sewaktu saya buka rekening di bank CIMB Niaga jalan Dago Bandung saya sudah mengaktifkan Rekening Ponsel CIMB Niaga saya dan mencobanya bersama dengan petugas teller dan berfungsi, tapi saat ini saya mendapatkan masalah saat mengirim uang ke Rekening Ponsel CIMB Niaga saya.

Error yang saya dapat saat mengirim uang ke Rekening ponsel saya adalah sebagai berikut:

ERROR ISO0007

Transaction failed.

Please try again later.Sorry for the inconvenience. If problem persists, please call 14041(local calls)/62-21-14041(overseas calls) mentioning the error code written on the top of your error message screen.

ponsel1ponsel4ponsel2ponsel5-error-iso0007

Saya sudah menghubungi pihak CIMB Niaga untuk mengetahuai bagaimana cara menyelesaikan masalah ini dan akan update pada post ini bila sudah ada solusi dan masukan dari pihak Bank CIMB Niaga.

Email balasan dari CIMB Niaga terkait error di Rekening Ponsel:

cimbniaga-balasanemail

 

Kelanjutannya akan saya update bila ada kabar terbaru dari pihak Bank CIMB Niaga.

 

nah setelah berhari-hari saya dapet lagi email dari CIMB Niaga jawabannya seperti ini:

Nomor Referensi  : e20170303-000351

Yth.Bapak. Yusuf Ibr.,

 

Menindaklanjuti email Bapak, kami informasikan bahwa proses tindak lanjut telah dilakukan dengan hasil sebagai berikut:

Mohon maaf atas kendala akses yang Bapak alami.

Mohon konfirmasinya kendala yang Bapak alami apakah untuk transaksi Cimb Clicks atau Go Mobile ? dan apakah masih mengalami kendala hingga saat ini ?

Bapak dapat memberikan balasan melalui email ini dalam kurun waktu 3 (tiga) hari kerja apabila terdapat hal yang ingin disampaikan.

Terima kasih atas kepercayaan Bapak kepada kami. Melayani Bapak merupakan kebanggaan bagi kami.

 

Hormat kami,    `

CIMB Niaga

————————————————————————————————————————————–

Original_mail

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

cimbniaga_email1

 

 

Golang: Error Handling in Go Programming

Return Error


package main

import (
	"errors"
	"fmt"
)

func sum(a int, b int) (int, error) {

	x := a + b

	if a < 0 || b < 0 {
		return x, errors.New("value should be greater than zero")
	}

	return x, nil
}

func main() {
	a := 12
	b := -1

	x, err := sum(a, b)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(x)
}

Panic and Recover from panic

package main

import (
	//	"errors"
	"fmt"
)

func sum(a int, b int) (int, error) {
	defer func() {
		if err := recover(); err != nil {
			fmt.Println("Wow Error: ", err)
		}
	}()

	x := a + b

	if a < 0 || b < 0 {
		panic("I am panicking kaka")
	}

	return x, nil
}

func main() {
	a := 12
	b := -1

	x, err := sum(a, b)

	fmt.Println(x)
	fmt.Println(err)
}

Golang: Structs Methods and Interface

Go Struct, Methods and Embedding example

package main

import "fmt"

type User struct {
	name, address string
}

type Employee struct {
	level  int
	salary int
	user   User // Embedding
}

/**
 * Greating for User
 */
func (u User) Greeting() string {
	return fmt.Sprintf("Dear %s %s", u.name, u.address)
}

/**
 * Greating for User
 */
func (e Employee) Greeting() string {
	return fmt.Sprintf("Your level %d, Your salary %d", e.level, e.salary)
}

func main() {
	user := User{"Yazid", "Jalan munukan no.19"}

	fmt.Println(user.Greeting())

	employee := Employee{1, 2000, user}

	fmt.Println(employee.user.Greeting())
	fmt.Println(employee.Greeting())
}

Using Pointer to keep the lowest amount of structs per file

package main

import (
	"fmt"
)

type User struct {
	FirstName, LastName string
}

func (u *User) Greeting() string {
	return fmt.Sprintf("Dear %s %s", u.FirstName, u.LastName)
}
func main() {
	u := &User{"Yusuf", "Ibrahim"}
	fmt.Println(u.Greeting())
}

Golang Interface Example

package main

import (
	"fmt"
)

type User struct {
	FirstName, LastName, address string
}

func (u *User) Name() string {
	return fmt.Sprintf("%s %s", u.FirstName, u.LastName)
}

func (u *User) Address() string {
	return fmt.Sprintf("%s", u.address)
}

type Customer struct {
	Id                int
	FullName, address string
}

func (c *Customer) Name() string {
	return c.FullName
}

func (c *Customer) Address() string {
	return fmt.Sprintf("%s", c.address)
}

type Namer interface {
	Name() string
	Address() string
}

func Greet(n Namer) string {
	return fmt.Sprintf("Dear %s at %s", n.Name(), n.Address())
}
func main() {
	u := &User{"Matt", "Aimonetti", "jalan Banda"}
	fmt.Println(Greet(u))

	c := &Customer{42, "Francesc", "jalan Banda"}
	fmt.Println(Greet(c))
}

Golang: Map, Hashes, Dictionary

Golang Maps are similar to what other language call ‘dictionaries’ or ‘hashes’.

 

package main

import "fmt"

var names = map[string]int{"Katrina": 10, "Evan": 11, "Neil": 12}

func main() {
    //  fmt.Printf("%#v", names)

    for x, _ := range names {
        fmt.Println(x)
    }
    // Output:
    // Katrina
    // Evan
    // Neil

    for _, name := range names {
        fmt.Println(name)
    }
    // Output:
    // 10
    // 11
    // 12

    for x, name := range names {
        fmt.Printf("%s : %d \n", x, name)
    }
    // Output
    // Katrina : 10
    // Evan : 11
    // Neil : 12

}

Add / Append new data to a map


package main

import "fmt"

func main() {
	names := make(map[string]int)
	//	fmt.Printf("%#v", names)

	names["jhony"] = 1
	names["beta"] = 2

	for x, name := range names {
		fmt.Printf("%s : %d \n", x, name)
	}

}

Collection of objects


package main

import "fmt"

type Person struct {
	name, address string
}

func main() {
	jelemas := make(map[string]Person)

	jelemas["Yoesoff"] = Person{"yusuf", "Jl. Wakwau no.09"}
	jelemas["Yuka"] = Person{"gokana", "Jl. Wakwau no.90"}
	jelemas["Mumun"] = Person{"pocong", "Jl. Wakwau no.99"}

	//	fmt.Printf("%#v", names)
	for x, wong := range jelemas {
		fmt.Printf("%s : %s (%s) \n", x, wong.name, wong.address)
	}

	// Output
	// Yuka : gokana (Jl. Wakwau no.90)
	// Mumun : pocong (Jl. Wakwau no.99)
	// Yoesoff : yusuf (Jl. Wakwau no.09) 

}

Remove / Delete item from map


package main

import "fmt"

type Person struct {
	name, address string
}

func main() {
	jelemas := make(map[string]Person)

	jelemas["Yoesoff"] = Person{"yusuf", "Jl. Wakwau no.09"}
	jelemas["Yuka"] = Person{"gokana", "Jl. Wakwau no.90"}
	jelemas["Mumun"] = Person{"pocong", "Jl. Wakwau no.99"}

	//	fmt.Printf("%#v", names)
	for x, wong := range jelemas {
		fmt.Printf("%s : %s (%s) \n", x, wong.name, wong.address)
	}

	// Output
	// Yuka : gokana (Jl. Wakwau no.90)
	// Mumun : pocong (Jl. Wakwau no.99)
	// Yoesoff : yusuf (Jl. Wakwau no.09)

	delete(jelemas, "Mumun")

	fmt.Println("Delete Mumun (Because he is scary)")
	for x, wong := range jelemas {
		fmt.Printf("%s : %s (%s) \n", x, wong.name, wong.address)
	}

	// Output
	// Delete Mumun (Because he is scary)
	// Yoesoff : yusuf (Jl. Wakwau no.09)
	// Yuka : gokana (Jl. Wakwau no.90)

}

Check Element existence in a map


	// Check Element
	_, ok := jelemas["Yuka"]

	fmt.Println(ok)

	_, ok = jelemas["Mumun"]

	fmt.Println(ok)