Sofian Hadiwijaya

Programming is a creative activity.

Pengenalan Bahasa Pemrogramman Golang

| Comments

Bulan lalu kantor saya kedatangan CTO dari Go-Jek (Sheran Gunasekera), beliau sharing tentang beberapa masalah yang dialami oleh Go-Jek, salah satunya yaitu masalah concurrency, untuk menyelesaikan masalah ini mereka berniat migrasi ke Go. Karena penasaran saya juga mencoba untuk belajar Go.

Inti dari saya menulis blog ini lebih ke memberi pengenalan tentang Go, bukan untuk mengajari bagaimana full tentang Go. Karena saya bukan orang yang menggunakan Go dalam keseharian. Tapi saya harap kedepannya dapat merubah beberapa webservice kami ke Go. Kenapa saya tertarik untuk migrasi ke Go, mari kita lihat sejarah dari Go sendiri.

Go dibuat oleh Robert Griesemer, Rob Pike dan Ken Thompson pada tahun 2007, dan mulai dipublish tahun 2009. Idenya sendiri lahir dari kebutuhan untuk membuat suatu bahasa pemrogramman yang type safety dan portability. Dan beberapa tujuan lainnya :

  • Gampang dipelajari
  • Type Safety dan Memory Safety
  • Gampang untuk Concurrency
  • Adanya Garbage Collection
  • Kompilasi yang cepat

Beberapa perusahaan besar yang telah menggunakan Go antara lain :

Untuk IDE sendiri beberapa IDE yang lazim digunakan oleh para developer telah mendukung Go, seperti :

Keseharian saya menggunakan beberapa dynamic language seperti Python dan Nodejs, ketika saya mencoba syntax Go cukup mudah untuk saya beradaptasi, namun walaupun demikian Go memiliki performa yang setara dengan C. Mari kita perhatikan beberapa hal yang membedakan Go dengan bahasa pemrogramman lainnya.

Syntax

Go tidak mengharuskan untuk menambahkan titik koma(;) pada setiap akhir dari baris kode. Untuk deklarasi sendiri ada beberapa cara diantaranya :

  • nama variable diikuti oleh tipe datanya ex : var kata string
  • variable juga bisa langsung diinisialisasi ex : angka := 10

Masih ingat ketika kita mengakses sebuah object biasanya ada property Public/Private, dimana yang memiliki proverty Private hanya bisa diakses oleh si object itu sendiri. Nah di Go sendiri yang membedakan Public dan Private adalah awal kata dari nama variable atau function tersebut. Ketika awal katanya merupakan huruf besar maka secara otomatis akan menjadi Public variable atau function. Sebaliknya untuk private cukup menggunakan awal katanya ke huruf kecil.

1
2
func Foo() // Public function
func bar() // Private function

Go merupakan bahasa pemrogramman procedural, dimana Go tidak mempunyai feature class, overloading, dan inheritance.

Warning / Error

Go juga mempunya karakteristik yang unik tentang Error. Jika ada variable atau package yang tidak terpakai maka akan ada peringatan Error.

Control Structure

Hal yang menarik dari Go hanya memiliki 3 Control Structure :

  • If Else
  • Switch Case
  • For

Untuk penulisan sendiri ada beberapa berbedaan seperti pada If Else kita bisa menginisialisasi variable pada kondisional statemen

ifelse.go
1
2
3
if value, ok := readData(); kondisional {
  ...
}

Begitu pula untuk Switch Case, pada Go lebih fleksibel. Karena kita harus menentukan variable apa yang akan menjadi acuan Case.

switch.go
1
2
3
4
5
6
7
8
switch {
  case i < 0:
      f1()
  case i == 0:
      f2()
  case i > 0:
      f3()
}

Selain itu Switch Case pada Go juga tidak mempunyai break. jika kita mau mengindikasikan dari satu Case satu mau lanjut ke Case selanjutnya kita perlu menambahkan Kode fallthrough

switch2.go
1
2
3
4
5
6
7
8
9
10
11
12
switch i {
  case 0: // tidak akan ada yang akan dieksekusi ketika i == 0
  case 1:
          f() // function f() tidak akan dipanggil ketika i == 0
}

// untuk membuat function f dipanggil kita perlu menambahkan failthrough pada case 1
switch i {
  case 0: failthrough
  case 1:
          f() // dengan demikian function f() akan dipanggil ketika i == 0
}

Dan yang paling menarik untuk metode pengulangan Go hanya memiliki satu control structure yaitu For, untuk membuat infinte loop kita bisa menuliskan sebagai berikut

for.go
1
2
3
for{
  
}

Tipe Data

Berikut tipe data yang ada pada Go :

  • Boolean : bool
  • Numeric : uint8 to uint64, int8 to int64, uint, int, float32, float64,complex64, complex128, byte, rune
  • String : string
  • Array : [5]byte
  • Slice : make([]int, 50, 100)
  • Map : map[string]int
  • Struct : struct
  • Function : func
  • Interface : interface
  • Channel : chan

Kurang lebih sama seperti bahasa lainnya, namun ada beberapa perbedaan yang akan kita bahas.

Array

Array merupakan tipe data yang dapat menampung data dengan tipe data yang sama. Pada Go Array memiliki kapasitas yang tetap dimana kita tidak bisa menambahkan data melebihi kapasitas dari array tersebut. Mirip dengan tuple pada Python.

array.go
1
2
3
4
5
6
7
8
9
10
11
12
13
package main

import "fmt"

func main() {
    var arr1 [5]int
    for i:=0; i < len(arr1); i++ {
      arr1[i] = i * 2
    }
    for i:=0; i < len(arr1); i++ {
      fmt.Printf("Array at index %d is %d\n", i, arr1[i])
  }
}
Output
1
2
3
4
5
Array at index 0 is 0
Array at index 1 is 2
Array at index 2 is 4
Array at index 3 is 6
Array at index 4 is 8

Slice

Bisa dibilang Slice merupakan Array yang fleksibel, maksudnya adalah kapasitas dari Slice bisa berubah, baik bertambah ataupun berkurang. Jika Anda programmer Python, maka Slice ini mirip dengan list pada Python.

slice.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package main

import "fmt"

func main() {
    var slice1 []int = make([]int, 10)
}

// load the array/slice:
for i := 0; i < len(slice1); i++ {
  slice1[i] = 5 * i
}

// print the slice:
for i := 0; i < len(slice1); i++ {
  fmt.Printf("Slice at %d is %d\n", i, slice1[i])
}

fmt.Printf("\nThe length of slice1 is %d\n", len(slice1))
fmt.Printf("The capacity of slice1 is %d\n", cap(slice1))
Output
1
2
3
4
5
6
7
8
9
10
11
Slice at 0 is 0
Slice at 1 is 5
Slice at 2 is 10
Slice at 3 is 15
Slice at 4 is 20
Slice at 5 is 25
Slice at 6 is 30
Slice at 7 is 35
Slice at 8 is 40
Slice at 9 is 45
The length of slice1 is 10

Map

Map juga merupakan Array, jika pada Array dan Slice untuk mengakses menggunakan index, pada Map Anda dapat menggunakan key, atau sering disebut juga hash. Pada Python Map dikenal sebagai Dictionary.

map.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

func main() {
    var mapLit map[string]int
    var mapAssigned map[string]int

  mapLit = map[string]int{"one": 1, "two": 2}
  mapCreated := make(map[string]float32)
  mapAssigned = mapLit
  
  mapCreated["key1"] = 4.5
  mapCreated["key2"] = 3.14159
  mapAssigned["two"] = 3
  
  fmt.Printf("Map literal at one is: %d\n", mapLit["one"])
  fmt.Printf("Map created at key2 is: %f\n", mapCreated["key2"])
  fmt.Printf("Map assigned at two is: %d\n", mapLit["two"])
  fmt.Printf("Map literal at ten is: %d\n" mapLit["ten"])
}
Output
1
2
3
4
Map literal at one is: 1
Map created at key2 is: 3.141590
Map assigned at two is: 3
Map literal at ten is: 0

Struct

Jika Array merupakan kumpulan data dengan tipe data yang sama, Struct adalah kumpulan data dengan tipe data yang berbeda sesuai dengan apa yang kita define diawal. Hal ini sangat mirip dengan konsepnya Struct pada Bahasa C.

konsep
1
2
3
4
5
type identifier struct {
  field1 type1
  field2 type2
  ...
}
struct.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

type struct1 struct {
  i1   int
  f1   float32
  str  string
}

func main() {
  ms := new(struct1)
  ms.i1 = 10
  ms.f1 = 15.5
  ms.str = "Chris"

  fmt.Printf("The int is: %d\n", ms.i1)
  fmt.Printf("The float is: %f\n", ms.f1)
  fmt.Printf("The string is: %s\n", ms.str)
  fmt.Println(ms)
}
Output
1
2
3
4
The int is: 10
The float is: 15.500000
The string is: Chris
&{10 15.5 Chris}

Function

Function merupakan kumpulan dari tipe data, control dan statement. Yang mana bisa mengembalikan value, tidak seperti bahasa pemrogramman pada umumnya, pada Go return value nya bisa lebih dari satu.

function.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package main

import "fmt"

func main(){
  nilai := []int{7,8,9,9}
  nama := "sofian hadiwijaya"

  nilairatarata, namanya := HitungAvg(nilai, nama)
  fmt.Printf("Nama Siswa: %s\n", namanya)    
  fmt.Printf("Nilai Rata-Rata: %f\n", nilairatarata) 

}

func HitungAvg(nilai []int, nama string) (float32, string) {
  var total int
  for i:=0; i < len(nilai); i++ {
      total += nilai[i]
  }
  return float32(total)/float32(len(nilai)), nama
}
Output
1
2
Nama Siswa: sofian hadiwijaya
Nilai Rata-Rata: 8.250000

Interface

Go bukan bahasa berorientasi objek ‘klasik’. Dimana Go tidak mempunyai class dan metode inheritance. Interface sendiri lebih ke seperti Abstract Class dimana hanya berupa kumpulan metode/function.

konsep
1
2
3
4
5
type Namer interface {
  Method1(param_list) return_type
  Method2(param_list) return_type
  ...
}
interface.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import "fmt"

type Shaper interface {
  Area() float32
}

type Square struct {
  side float32
}

func (sq *Square) Area() float32 {
  return sq.side * sq.side
}

func main(){
  sq1 := new(Square)
  sq1.side = 5

  areaIntf := sq1
  fmt.Printf("Luas Area = %f\n", areaIntf.Area())
}
Output
1
Luas Area = 25.000000

Goroutines And Channel

Goroutines merupakan thread pada bahasa pemrogramman lainnya.

Do not use global variables or shared memory, they make your code unsafe for running concurrently

Channel sendiri merupakan alat komunikasi antara goroutines

goroutine.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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)
}
Output
1
17 -5 12

Selamat mencoba, jika Anda ingin belajar lebih lanjut dapat langsung mengunjungi situs dokumentasi dari Go

Comments