Pendahuluan

  • Go-Lang, selain merupakan bahasa pemrograman, Go-Lang juga menyediakan Standard Library (package bawaan) tanpa harus menggunakan package dari luar buatan orang lain
  • Contoh pada Kelas Golang Dasar, kita sudah belajar package bernama fmt atau errors
  • Selain package tersebut, sebenarnya masih banyak package lainnya yang bisa kita gunakan

Membuat Project

$ go mod init `standard-library`

Package fmt

souce:: https://pkg.go.dev/fmt

  • Sebelumnya kita sudah sering menggunakan package fmt dengan menggunakan function Println
  • Selain Println, masih banyak function yang terdapat di package fmt, contohnya banyak digunakan untuk melakukan format
package main
 
import "fmt"
 
func main() {
	firstName := "Rahmat"
	lastName := "Ardiansyah"
 
	fmt.Printf("Hello '%s %s'\n", firstName, lastName)
}
➜ go run fmt.go 
Hello 'Rahmat Ardiansyah'
 

Package errors

source:: https://pkg.go.dev/errors

  • Sebelumnya kita sudah membahas tentang interface error yang merupakan representasi dari error di Go-Lang, dan membuat error menggunakan function errors.New()
  • Masih banyak yang bisa kita lakukan menggunakan package errors, contohnya ketika kita ingin membuat beberapa value error yang berbeda
package main
 
import (
	"errors"
	"fmt"
)
 
var (
	ValidatorError = errors.New("validator error")
	NotFoundError  = errors.New("not found error")
)
 
func GetById(id string) error {
	if id == "" {
		return ValidatorError
	}
 
	if id != "rahmat" {
		return NotFoundError
	}
 
	return nil
}
 
func main() {
 
	err := GetById("rahmat")
 
	if err != nil {
		if errors.Is(err, ValidatorError) {
			fmt.Println("Validation Error")
		} else if errors.Is(err, NotFoundError) {
			fmt.Println("Not Found Error")
		} else {
			fmt.Println("Unknown Error")
		}
	}
 
}
learn/go/standard-library via 🐹 v1.25.4 
➜ go run error.go 
Validation Error
 
learn/go/standard-library via 🐹 v1.25.4 
➜ go run error.go 
 

Package os

source:: https://golang.org/pkg/os/

  • Go-Lang telah menyediakan banyak sekali package bawaan, salah satunya adalah package os
  • Package os berisikan fungsionalitas untuk mengakses fitur sistem operasi secara independen (bisa digunakan disemua sistem operasi)
package main
 
import (
	"fmt"
	"os"
)
 
func main() {
	args := os.Args
 
	fmt.Println(args)
}
➜ go run os.go 10 20 30
[/tmp/go-build3002110511/b001/exe/os 10 20 30]
  • os.Args untuk mengambil argument user saat menjalankan aplikasinya
package main
 
import (
	"fmt"
	"os"
)
 
func main() {
	hostname, error := os.Hostname()
 
	if error == nil {
		fmt.Println(hostname)
	} else {
		fmt.Println(error.Error())
	}
}
➜ go run os.go 
arch
  • os.Hostname() untuk mendapatkan nama hostname dari device yang digunakan

Package flag

source:: https://golang.org/pkg/flag/

  • Package flag berisikan fungsionalitas untuk mem-parsing command line argument
package main
 
import (
	"flag"
	"fmt"
)
 
func main() {
	var username *string = flag.String("username", "root", "database username")
	var password *string = flag.String("password", "root", "database password")
	var host *string = flag.String("host", "localhost", "database host")
	var port *int = flag.Int("port", 0, "database port")
 
	flag.Parse()
 
	fmt.Println("Username:", *username)
	fmt.Println("Password:", *password)
	fmt.Println("Host:", *host)
	fmt.Println("Port:", *port)
}
learn/go/standard-library via 🐹 v1.25.4 
➜ go run flag.go 
Username: root
Password: root
Host: localhost
Port: 0
 
learn/go/standard-library via 🐹 v1.25.4 
➜ go run flag.go -username=rahmat -password=12321 -host=121.2.3.12 -port=8080
Username: rahmat
Password: 12321
Host: 121.2.3.12
Port: 8080
  • Jika tidak ada argument yang dikirim maka akan mengembalikan default valuenya

Package strings

source:: https://golang.org/pkg/strings/

  • Package strings adalah package yang berisikan function-function untuk memanipulasi tipe data String

Function di Package strings

FunctionKegunaan
strings.Trim(string, cutset)Memotong cutset di awal dan akhir string
strings.ToLower(string)Membuat semua karakter string menjadi lower case
strings.ToUpper(string)Membuat semua karakter string menjadi upper case
strings.Split(string, separator)Memotong string berdasarkan separator
strings.Contains(string, search)Mengecek apakah string mengandung string lain
strings.ReplaceAll(string, from, to)Mengubah semua string dari from ke to
package main
 
import (
	"fmt"
	"strings"
)
 
func main() {
	fmt.Println(strings.Contains("Rahmat", "mat"))
	fmt.Println(strings.Split("Rahmat Ardiansyah", " "))
	fmt.Println(strings.ToLower("Rahmat Ardiansyah"))
	fmt.Println(strings.ToUpper("Rahmat Ardiansyah"))
	fmt.Println(strings.Trim("   Rahmat Ardiansyah   ", " "))
	fmt.Println(strings.Replace("mat Ardiansyah", "mat", "Rahmat", 1))
}
➜ go run strings.go 
true
[Rahmat Ardiansyah]
rahmat ardiansyah
RAHMAT ARDIANSYAH
Rahmat Ardiansyah
Rahmat Ardiansyah

Package strconv

source:: https://golang.org/pkg/strconv/

  • Sebelumnya kita sudah belajar cara konversi tipe data, misal dari int32 ke int64
  • Bagaimana jika kita butuh melakukan konversi yang tipe datanya berbeda? Misal dari int ke string, atau sebaliknya
  • Hal tersebut bisa kita lakukan dengan bantuan package strconv (string conversion)

Function di Package strconv

FunctionKegunaan
strconv.parseBool(string)Mengubah string ke bool
strconv.parseFloat(string)Mengubah string ke float
strconv.parseInt(string)Mengubah string ke int64
strconv.FormatBool(bool)Mengubah bool ke string
strconv.FormatFloat(float, … )Mengubah float64 ke string
strconv.FormatInt(int, … )Mengubah int64 ke string
package main
 
import (
	"fmt"
	"strconv"
)
 
func main() {
	b, err := strconv.ParseBool("false")
	if err != nil {
		fmt.Println(err.Error())
	} else {
		fmt.Println(b)
	}
}
learn/go/standard-library via 🐹 v1.25.4 
➜ go run strconv.go 
strconv.ParseBool: parsing "SALAH": invalid syntax
 
learn/go/standard-library via 🐹 v1.25.4 
➜ go run strconv.go 
false
package main
 
import (
	"fmt"
	"strconv"
)
 
func main() {
	binary := strconv.FormatInt(999, 2)
 
	fmt.Println(binary) // 1111100111
}

Package math

source:: https://golang.org/pkg/math/

  • Package math merupakan package yang berisikan constant dan fungsi matematika

Function di Package math

FunctionKegunaan
math.Round(float64)Membulatkan float64 keatas atau kebawah, sesuai dengan yang paling dekat
math.Floor(float64)Membulatkan float64 kebawah
math.Ceil(float64)Membulatkan float64 keatas
math.Max(float64, float64)Mengembalikan nilai float64 paling besar
math.Min(float64, float64)Mengembalikan nilai float64 paling kecil
package main
 
import (
	"fmt"
	"math"
)
 
func main() {
	fmt.Println(math.Ceil(1.40))
	fmt.Println(math.Floor(1.40))
	fmt.Println(math.Round(1.40))
	fmt.Println(math.Max(1, 2))
	fmt.Println(math.Min(1, 2))
}

Package container/list

source:: https://golang.org/pkg/container/list/

  • Package container/list adalah implementasi struktur data double linked list di Go-Lang
  • Digunakan biasanya untuk atrian atau tumpukan

package main
 
import (
	"container/list"
	"fmt"
)
 
func main() {
	var data *list.List = list.New()
 
	data.PushBack("Rahmat")
	data.PushBack("Ardiansyah")
	data.PushBack("24")
 
	var head *list.Element = data.Front()
	fmt.Println(head.Value)               // Rahmat
	fmt.Println(head.Next().Value)        // Ardiansyah
	fmt.Println(head.Next().Next().Value) // 24
 
	fmt.Println("FOR LOOP")
	for el := data.Front(); el != nil; el = el.Next() {
		fmt.Println(el.Value)
	}
}
➜ go run double_link_list.go 
Rahmat
Ardiansyah
24
FOR LOOP
Rahmat
Ardiansyah
24

Package container/ring

source:: https://golang.org/pkg/container/ring/

  • Package container/ring adalah implementasi struktur data circular list
  • Circular list adalah struktur data ring, dimana diakhir element akan kembali ke element awal (HEAD)

package main
 
import (
	"container/ring"
	"fmt"
	"strconv"
)
 
func main() {
	var data *ring.Ring = ring.New(5)
 
	// data.Value = "Value 1"
	// data.Next().Value = "Value 2"
	// data.Next().Next().Value = "Value 3"
	// data.Next().Next().Next().Value = "Value 4"
	// data.Next().Next().Next().Next().Value = "Value 5"
 
	// data.Value = "Value 1"
 
	// data = data.Next()
	// data.Value = "Value 2"
 
	// data = data.Next()
	// data.Value = "Value 3"
 
	// data = data.Next()
	// data.Value = "Value 4"
 
	// data = data.Next()
	// data.Value = "Value 5"
 
	for i := 0; i < data.Len(); i++ {
		data.Value = "Value " + strconv.Itoa(i)
		data = data.Next()
	}
 
	data.Do(func(value any) {
		fmt.Println(value)
	})
}

Package sort

source:: https://golang.org/pkg/sort/

  • Package sort adalah package yang berisikan utilitas untuk proses pengurutan
  • Agar data kita bisa diurutkan, kita harus mengimplementasikan kontrak di interface sort.Interface
package main
 
import (
	"fmt"
	"sort"
)
 
type User struct {
	Name string
	Age  int
}
 
type UserSlice []User
 
func (s UserSlice) Len() int {
	return len(s)
}
 
func (s UserSlice) Less(i, j int) bool {
	return s[i].Age < s[j].Age
}
 
func (s UserSlice) Swap(i, j int) {
	s[i], s[j] = s[j], s[i]
}
 
func main() {
	users := []User{
		{"Rahmat", 24},
		{"Budi", 35},
		{"Joko", 30},
		{"Adit", 20},
	}
 
	sort.Sort(UserSlice(users))
 
	fmt.Println(users)
}

Package time

source:: https://golang.org/pkg/time/

  • Package time adalah package yang berisikan fungsionalitas untuk management waktu di Go-Lang

Function di Package time

FunctionKegunaan
time.Now()Untuk mendapatkan waktu saat ini
time.Date(…)Untuk membuat waktu
time.Parse(layout, string)Untuk memparsing waktu dari string
package main
 
import (
	"fmt"
	"time"
)
 
func main() {
	now := time.Now()
 
	fmt.Println(now)
 
	var utc time.Time = time.Date(2009, time.August, 17, 0, 0, 0, 0, time.UTC)
 
	fmt.Println(utc)
	fmt.Println(utc.Local())
 
	formatter := "2006-01-02 15:04:05"
 
	value := "2020-10-10 10:10:10"
 
	valueTime, error := time.Parse(formatter, value)
 
	if error != nil {
		fmt.Println(error.Error())
	} else {
		fmt.Println(valueTime)
	}
}
2025-12-02 13:47:28.608221591 +0700 WIB m=+0.000011804
2009-08-17 00:00:00 +0000 UTC
2009-08-17 07:00:00 +0700 WIB
2020-10-10 10:10:10 +0000 UTC

Duration

  • Saat menggunakan tipe data waktu, kadang kita butuh data berupa durasi
  • Package tipe memiliki type Duration, yang sebenarnya adalah alias untuk int64
  • Namun terdapat banyak method yang bisa kita gunakan untuk memanipulasi Duration
  • Biasanya digunakan untuk mengasih timeout seperti connect ke database
package main
 
import (
	"fmt"
	"time"
)
 
func main() {
	var duration1 time.Duration = 100 * time.Second
	var duration2 time.Duration = 10 * time.Millisecond
	var duration3 time.Duration = duration1 - duration2
 
	fmt.Println(duration3)
}

Package reflect

source:: https://golang.org/pkg/reflect/

  • Dalam bahasa pemrograman, biasanya ada fitur Reflection, dimana kita bisa melihat struktur kode kita pada saat aplikasi sedang berjalan
  • Hal ini bisa dilakukan di Go-Lang dengan menggunakan package reflect
  • Reflection sangat berguna ketika kita ingin membuat library yang general sehingga mudah digunakan
package main
 
import (
	"fmt"
	"reflect"
)
 
type Sample struct {
	Name string
}
 
type Person struct {
	Name, Address string
	Age           int
}
 
func readField(value any) {
	var valueType reflect.Type = reflect.TypeOf(value)
 
	fmt.Println("Type Name", valueType.Name())
 
	for i := 0; i < valueType.NumField(); i++ {
		var valueType reflect.StructField = valueType.Field(i)
		fmt.Println(valueType.Name)
		fmt.Println(valueType.Type)
	}
 
}
 
func main() {
	readField(Sample{"Rahmat"})
	readField(Person{"Rahmat", "Riau", 24})
}
➜ go run reflect.go 
Type Name Sample
Name
string
Type Name Person
Name
string
Address
string
Age
int
package main
 
import (
	"fmt"
	"reflect"
)
 
type Sample struct {
	Name string `required:"true" max:"10"`
}
 
type Person struct {
	Name    string `required:"true" max:"10"`
	Address string `required:"true" max:"30"`
	Age     int    `required:"true" max:"100"`
}
 
func isValid(value any) (result bool) {
	t := reflect.TypeOf(value)
	for i := 0; i < t.NumField(); i++ {
		var structField reflect.StructField = t.Field(i)
 
		if structField.Tag.Get("required") == "true" {
			data := reflect.ValueOf(value).Field(i).Interface()
			result = data != ""
			if result == false {
				return result
			}
		}
 
	}
	return result
}
 
func main() {
	person := Person{"Rahmat", "", 24}
 
	fmt.Println(isValid(person))
}
➜ go run reflect.go 
false

Package regexp

source:: https://golang.org/pkg/regexp/

  • Package regexp adalah utilitas di Go-Lang untuk melakukan pencarian regular expression
  • Regular expression di Go-Lang menggunakan library C yang dibuat Google bernama RE2
  • https://github.com/google/re2/wiki/Syntax

Function di Package regexp

FunctionKegunaan
regexp.MustCompile(string)Membuat Regexp
Regexp.MatchString(string) boolMengecek apakah Regexp match dengan string
Regexp.FindAllString(string, max)Mencari string yang match dengan maximum jumlah hasil
package main
 
import (
	"fmt"
	"regexp"
)
 
func main() {
	var regex *regexp.Regexp = regexp.MustCompile(`m([a-z])t`)
 
	fmt.Println(regex.MatchString("mat"))
	fmt.Println(regex.MatchString("met"))
	fmt.Println(regex.MatchString("mAt"))
}
➜ go run regex.go 
true
true
false
package main
 
import (
	"fmt"
	"regexp"
)
 
func main() {
	var regex *regexp.Regexp = regexp.MustCompile(`m([a-z])t`)
	fmt.Println(regex.FindAllString("mat met mut tam", 4))
}
➜ go run regex.go
[mat met mut]

Package encoding

source:: https://pkg.go.dev/encoding

  • Golang menyediakan package encoding untuk melakukan encode dan decode
  • Golang menyediakan berbagai macam algoritma untuk encoding, contoh yang populer adalah base64, csv dan json

base64

package main
 
import (
	"encoding/base64"
	"fmt"
)
 
func main() {
	value := "Rahmat Ardiansyah"
 
	encoded := base64.StdEncoding.EncodeToString([]byte(value))
 
	fmt.Println("Encoded", encoded)
 
	decoded, error := base64.StdEncoding.DecodeString(encoded)
 
	if error != nil {
		fmt.Println(error.Error())
	} else {
		fmt.Println("Decoded", string(decoded))
	}
}

CSV Reader

package main
 
import (
	"encoding/csv"
	"fmt"
	"io"
	"strings"
)
 
func main() {
	csvString := "Rahmat, Ardiansyah, 24\n" +
		"Budi, Pratama, 30\n" +
		"Joko, morro, diah, 40"
 
	reader := csv.NewReader(strings.NewReader(csvString))
 
	for {
		record, error := reader.Read()
		if error == io.EOF {
			break
		}
		fmt.Println(record)
	}
}

CSV Writer

package main
 
import (
	"encoding/csv"
	"os"
)
 
func main() {
	writer := csv.NewWriter(os.Stdout)
	_ = writer.Write([]string{"Rahmat", "Ardiansyah", "24"})
	_ = writer.Write([]string{"Budi", "Pratama", "30"})
	_ = writer.Write([]string{"Joko", "Morro", "34"})
	writer.Flush()
}

Package slices

source:: https://pkg.go.dev/slices

  • Di Golang versi terbaru, terdapat fitur bernama Generic, fitur Generic ini membuat kita bisa membuat parameter dengan tipe yang bisa berubah-ubah, tanpa harus menggunakan interface kosong / any
  • Salah satu package yang menggunakan fitur Generic ini adalah package slices
  • Package slices ini digunakan untuk memanipulasi data di slice
package main
 
import (
	"fmt"
	"slices"
)
 
func main() {
	names := []string{"Jhon", "Paul", "George", "Ringo"}
	fmt.Println(slices.Max(names))
	fmt.Println(slices.Min(names))
	fmt.Println(slices.Contains(names, "Paul"))
	fmt.Println(slices.Index(names, "Paul"))
	fmt.Println(slices.Index(names, "Mat"))
 
	values := []int{100, 80, 90, 95}
	fmt.Println(slices.Max(values))
	fmt.Println(slices.Min(values))
}

Package path

source::

  • https://pkg.go.dev/path

  • https://pkg.go.dev/path/filepath

  • Package path digunakan untuk memanipulasi data path seperti path di URL atau path di File System

  • Secara default Package path menggunakan slash sebagai karakter path nya, oleh karena itu cocok untuk data URL

  • Namun jika ingin menggunakan untuk memanipulasi path di File System, karena Windows menggunakan backslash, maka khusus untuk File System, perlu menggunakan package path/filepath

package main
 
import (
	"fmt"
	"path"
)
 
func main() {
	fmt.Println(path.Dir("hello/world.go"))
	fmt.Println(path.Base("hello/world.go"))
	fmt.Println(path.Ext("hello/world.go"))
	fmt.Println(path.Join("hello/world/main.go"))
}
➜ go run path.go 
hello
world.go
.go
hello/world/main.go
package main
 
import (
	"fmt"
	"path/filepath"
)
 
func main() {
	fmt.Println(filepath.Dir("hello/world.go"))
	fmt.Println(filepath.Base("hello/world.go"))
	fmt.Println(filepath.Ext("hello/world.go"))
	fmt.Println(filepath.Join("hello/world/main.go"))
}
➜ go run filepath.go 
hello
world.go
.go
hello/world/main.go

Package io

source:: https://pkg.go.dev/io

  • IO atau singkatan dari Input Output, merupakan fitur di Golang yang digunakan sebagai standard untuk proses Input Output
  • Di Golang, semua mekanisme input output pasti mengikuti standard package io

Reader

  • Untuk membaca input, Golang menggunakan kontrak interface bernama Reader yang terdapat di package io
package main
 
import (
	"bufio"
	"fmt"
	"io"
	"strings"
)
 
func main() {
	input := strings.NewReader("This is long string\nwith new line\n")
 
	reader := bufio.NewReader(input)
 
	for {
		line, _, error := reader.ReadLine()
		if error == io.EOF {
			break
		}
		fmt.Println(string(line))
	}	
}

Writer

  • Untuk menulis ke output, Golang menggunakan kontrak interface bernama Writer yang terdapat di package io
package main
 
import (
	"bufio"
	"os"
)
 
func main() {
	writer := bufio.NewWriter(os.Stdout)
	_, _ = writer.WriteString("Hello world\n")
	_, _ = writer.WriteString("Belajar Golang\n")
	writer.Flush()
}

Implementasi IO

  • Penggunaan dari IO sendiri di Golang terdapat dibanyak package, sebelumnya contohnya kita menggunakan CSV Reader dan CSV Writer
  • Karena Package IO sebenarnya hanya kontrak untuk IO, untuk implementasinya kita harus lakukan sendiri
  • Tapi untungnya, Golang juga menyediakan package untuk mengimplementasikan IO secara mudah, yaitu menggunakan package bufio

Package bufio

source:: https://pkg.go.dev/bufio

  • Package bufio atau singkatan dari buffered io
  • Package ini digunakan untuk membuat data IO seperti Reader dan Writer

File Manipulation

File Management

  • Saat kita membuat atau membaca file menggunakan Package os, struct File merupakan implementasi dari io.Reader dan io.Writer
  • Oleh karena itu, kita bisa melakukan baca dan tulis terhadap File tersebut menggunakan Package io / bufio

Open File

  • Untuk membuat / membaca File, kita bisa menggunakan os.OpenFile(name, flag, permission)
  • name berisikan nama file, bisa absolute atau relative / local
  • flag merupakan penanda file, apakah untuk membaca, menulis, dan lain-lain
  • permission, merupakan permission yang diperlukan ketika membuat file, bisa kita simulasikan disini : https://chmod-calculator.com/
package main
 
import (
	"bufio"
	"fmt"
	"io"
	"os"
)
 
func createNewFile(name string, message string) error {
	file, err := os.OpenFile(name, os.O_CREATE|os.O_WRONLY, 0666)
	if err != nil {
		return err
	}
 
	defer file.Close()
	file.WriteString(message)
	return nil
 
}
 
func readFile(name string) (string, error) {
	file, err := os.OpenFile(name, os.O_RDONLY, 0666)
	if err != nil {
		return "", err
	}
 
	defer file.Close()
 
	reader := bufio.NewReader(file)
	var message string
	for {
		line, _, err := reader.ReadLine()
		if err == io.EOF {
			break
		} else {
			message += string(line) + "\n"
		}
	}
	return message, nil
}
 
func addToFile(name string, message string) error {
	file, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0666)
	if err != nil {
		return err
	}
 
	defer file.Close()
	file.WriteString(message)
	return nil
 
}
 
func main() {
	createNewFile("sample.log", "This is sample text")
	result, _ := readFile("sample.log")
	addToFile("sample.log", "\ntambah line baru")
	fmt.Printf(result)
}

Package Lainnya