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 packagefmt, 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
osberisikan 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.Argsuntuk 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
archos.Hostname()untuk mendapatkan nama hostname dari device yang digunakan
Function stat
source:: https://pkg.go.dev/os#Stat
- Lstats mengembalikan sebuah FileInfo
- Lstat juga mengembalikan sebuah error, jika erro akan mengembalikan PathError
package main
import (
"errors"
"fmt"
"os"
)
func main() {
logFile := "example.log"
exist, err := fileExists(logFile)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("File exists:", exist)
}
func fileExists(path string) (bool, error) {
_, err := os.Stat(path)
switch {
case err == nil:
// file ditemukan
return true, nil
case errors.Is(err, os.ErrNotExist):
// file tidak ditemukan
return false, nil
default:
// error lain, misal permission denied
return false, err
}
}- Coding diatas digunakan untuk pengecekan apakah file tersebut ada atau tidak
- Jika ada kembalikan true dan jika tidak kembalikan false
Function Lstat
source:: https://pkg.go.dev/os#Lstat
- Lstats mengembalikan sebuah FileInfo
- Jika file adalah sebuah symbolic link akan mengembalikan description itu symbolic link
- Lstat juga mengembalikan sebuah error, akan mengembalikan PathError
package main
import (
"errors"
"fmt"
"os"
)
func main() {
path := "example.symlink"
isLink, err := isSymlink(path)
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Is symbolic link:", isLink)
}
func isSymlink(path string) (bool, error) {
info, err := os.Lstat(path)
if err != nil {
// Jika path tidak ada → bukan symlink, tapi bukan error kritis
if errors.Is(err, os.ErrNotExist) {
return false, nil
}
// Error lain → perlu di-handle caller
return false, err
}
// Mengecek apakah file mode menunjukkan symlink
return info.Mode()&os.ModeSymlink != 0, nil
}
- Coding diatas untuk cek apakah file tersebut merupakan symbolic link?
- jika iya kembalikan true, jika false kembalikan tidak
Function Create
source:: https://pkg.go.dev/os#Create
Create creates or truncates the named file. If the file already exists, it is truncated. If the file does not exist, it is created with mode 0o666 (before umask). If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR. The directory containing the file must already exist. If there is an error, it will be of type *PathError.
- Function create berfungsi untuk membuat file
- Jika file sudah ada akan menimpa file tersebut
- Jika belum ada maka akan membuat file dan permissionnya
666 - Jika sukses kita bisa menggunakan method dari IO
- Saat membuat file, directorynya sudah harus ada sebelumnya
- function create juga mengembalikan error
package main
import (
"errors"
"fmt"
"os"
)
func main() {
newPath := "new/file.txt"
fmt.Println("file created", createFile(newPath))
}
func createFile(path string) error {
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return nil
}➜ go run create_file.go
File exists: true
Is symbolic link: true
file created open neww/file.txt: no such file or directory
➜ go run create_file.go
File exists: true
Is symbolic link: true
file created open new/file.txt: permission denied
➜ go run create_file.go
File exists: true
Is symbolic link: true
file created <nil>
➜ go run create_file.go
File exists: true
Is symbolic link: true
file created <nil>- Coding diatas bertujuan untuk membuat file di dalam folder
new/bernamafile.txt - Jika folder belum ada maka akan mengembalikan error
no such file or directory - JIka sudah ada tapi permission nya tidak boleh menulis akan mengembalikan error
permission denied - Jika folder sudah ada dan permission bisa menulis maka file tersebut akan dibuat
- Jika file sudah ada dan menjalankan kode kembali maka akan menimpa file sebelumnya atau disebut truncation
Catatan
- Ketika membuka file di golang akan mengkonsumsi resource seperti memory dan file descriptor
- Jika kita tidak menutup file tersebut akan terus memakan resource dan terjadi memory leak
File Descriptor
File descriptor di Go adalah nomor integer unik yang digunakan sistem operasi untuk mengidentifikasi file atau sumber daya I/O (Input/Output) yang terbuka oleh sebuah program,
Function Mkdir & MkdirAll
source::
-
Mkdir&MkdirAlldigunakan untuk membuat folder -
Menerima 2 argument, yaitu path (string) dan permission (FileMode)
-
Mkdir&MkdirAllakan return nil atau error -
Jika folder belum ada atau sudah ada sebelumnya maka akan return nil (tidak error)
-
Perbedaan
Mkdir&MkdirAll:Mkdirhanya membuat 1 folder saja, tidak bisaos.Mkdir("a/b/c", 0755)MkdirAllbisa membuat banyak folder termasuk subfolderos.MkdirAll("a/b/c", 0755)
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
newPath := "new/file.txt"
if err := createFile(newPath); err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("File created successfully")
}
func createFile(path string) error {
// Pastikan direktori tujuan sudah ada
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed creating directory: %w", err)
}
// Buat file baru (overwrite jika sudah ada)
f, err := os.Create(path)
if err != nil {
return fmt.Errorf("failed creating file: %w", err)
}
defer f.Close()
return nil
}- coding diatas membuat file beserta folder dan subfoldernya jika belum ada (menggunakan
MkdirAll)
Function Open & OpenFile
Open&OpenFilefungsi pembuka file yang paling fleksibelOpenhanya bisa read-only sedangkanOpenFile(flag):- Baca saja
- Tulis saja
- Baca dan tulis
- Append atau menambah baris baru
- Hapus isinya atau truncation
- dan lainnya
OpenFilemenerima 3 argument
| Flag | Fungsi |
|---|---|
O_RDONLY | Buka file untuk baca |
O_WRONLY | Buka file untuk tulis |
O_RDWR | Buka file untuk baca + tulis |
O_APPEND | Tulis selalu di akhir |
O_CREATE | Buat file kalau belum ada |
O_EXCL | Error jika file sudah ada (harus dengan O_CREATE) |
O_TRUNC | Kosongkan isi file |
O_SYNC | Tulis sinkron ke storage |
O_DSYNC | Sinkron data saja |
O_NOCTTY | Jangan jadikan terminal sebagai controlling terminal |
O_NONBLOCK | Buka file non-blocking |
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
newPath := "folder/file.txt"
fmt.Println(createFileIfNotExist(newPath))
}
func createFileIfNotExist(path string) error {
file, err := os.OpenFile(path, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0755)
if err != nil {
return err
}
defer file.Close()
return nil
}- Koding diatas untuk membuat
file.txt - Jika folder
folderbelum ada maka akan mengembalikanopen folder/file.txt: no such file or directory - Jika folder
foldersudah ada maka akan berhasil membuat file - Jika folder dan file sudah ada maka akan mengembalikan
open folder/file.txt: file exists
Function Write & WriteFile
source:: https://pkg.go.dev/os#WriteFile
Write&WriteFileberfungsi untuk menulis text ke dalam fileWriteFileberbeda denganWrite, karenaWriteFileakan menimpa isi dari konten sebelumnya dengan yang baruWriteFilemenerima 3 argument:namestringdata[]bytepermFileMode
WriteFileMengembalikan error, misalnya jika permission file read-only
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
newPath := "folder/file.txt"
fmt.Println("file created", createFile(newPath))
fmt.Println(createFileIfNotExist(newPath))
fmt.Println("Write file", writeFile(newPath, []byte("Hello World")))
}
func createFile(path string) error {
// Pastikan direktori tujuan sudah ada
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed creating directory: %w", err)
}
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return nil
}
func createFileIfNotExist(path string) error {
file, err := os.OpenFile(path, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0755)
if err != nil {
return err
}
defer file.Close()
return nil
}
func writeFile(path string, data []byte) error {
return os.WriteFile(path, data, 0644)
}➜ go run write_file.go
file created <nil>
open folder/file.txt: file exists
Write file <nil>- Koding diatas untuk membuat menulis file di
folder/file.txtyang berisiHello World - Jika permission file tidak bisa write akan error:
Write file open folder/file.txt: permission denied
Beriku adalah contoh koding untuk write:
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
newPath := "folder/file.txt"
fmt.Println("file created", createFile(newPath))
fmt.Println(createFileIfNotExist(newPath))
fmt.Println("Write file", writeFile(newPath, []byte("Hello World\n")))
fmt.Println("Append file", appendFile(newPath, []byte("Create New Line")))
}
func createFile(path string) error {
// Pastikan direktori tujuan sudah ada
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed creating directory: %w", err)
}
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return nil
}
func createFileIfNotExist(path string) error {
file, err := os.OpenFile(path, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0755)
if err != nil {
return err
}
defer file.Close()
return nil
}
func writeFile(path string, data []byte) error {
return os.WriteFile(path, data, 0644)
}
func appendFile(path string, data []byte) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0755)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(data)
return err
}appendFileberfungsi untuk menambahakan baris ke file yang sudah ada sebelumnya (tidak menimpannya)
Function ReadFile
ReadFiledigunakan untuk membaca sebuah fileReadFilemenerima 1 buah argument:namestring
- Mengembalikan 2 buah value, yaitu
[]bytedanerror
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
newPath := "folder/file.txt"
fmt.Println("file created", createFile(newPath))
fmt.Println(createFileIfNotExist(newPath))
fmt.Println("Write file", writeFile(newPath, []byte("Hello World\n")))
fmt.Println("Append file", appendFile(newPath, []byte("Create New Line")))
data, _ := readFile(newPath)
fmt.Println("Read file", string(data))
}
func createFile(path string) error {
// Pastikan direktori tujuan sudah ada
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed creating directory: %w", err)
}
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return nil
}
func createFileIfNotExist(path string) error {
file, err := os.OpenFile(path, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0755)
if err != nil {
return err
}
defer file.Close()
return nil
}
func writeFile(path string, data []byte) error {
return os.WriteFile(path, data, 0644)
}
func appendFile(path string, data []byte) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0755)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(data)
return err
}
func readFile(path string) ([]byte, error) {
return os.ReadFile(path)
}- Koding diatas bertujuan untuk readFile dari argument
newFiledan di convert dari byte ke string
Function Remove & RemoveAll
- function
Remove&RemoveAlldigunakan untuk menghapus file atau folder - Perbedaannya jika menghapus folder menggunakan
Removetidak bisa jika folder tersebut ada isinya, tapi bisa menggunakanRemoveAll - keduanya menerima 1 argument:
namestring
- dan mengembalikan error, misalnya jika permission write tidak ada
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
)
func main() {
fmt.Println("Delete file", deleteFile(("foldernih")))
}
func deleteFile(path string) error {
return os.Remove(path)
// return os.RemoveAll(path) // atau
}RemoveAllakan menghapus file atau folder(beserta isinya)
function Stats dan Lstats
- kedua function untuk mendapatkan info dari file atau folder seperti size, modified time dan lainnya
- Menerima 1 argumen:
namestring
- mengembalikan struct
FileInfodan error
package main
import (
"errors"
"fmt"
"os"
"path/filepath"
"time"
)
func main() {
newPath := "folder/file.txt"
fmt.Println("file created", createFile(newPath))
fmt.Println(createFileIfNotExist(newPath))
fmt.Println("Write file", writeFile(newPath, []byte("Hello World\n")))
fmt.Println("Append file", appendFile(newPath, []byte("Create New Line")))
data, _ := readFile(newPath)
fmt.Println("Read file", string(data))
fmt.Println("Delete file", deleteFile(("foldernih")))
size, modTime, _ := fileStats(newPath)
fmt.Println("File size", size)
fmt.Println("File modified", modTime)
}
func createFile(path string) error {
// Pastikan direktori tujuan sudah ada
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0755); err != nil {
return fmt.Errorf("failed creating directory: %w", err)
}
file, err := os.Create(path)
if err != nil {
return err
}
defer file.Close()
return nil
}
func createFileIfNotExist(path string) error {
file, err := os.OpenFile(path, os.O_RDWR|os.O_EXCL|os.O_CREATE, 0755)
if err != nil {
return err
}
defer file.Close()
return nil
}
func writeFile(path string, data []byte) error {
return os.WriteFile(path, data, 0644)
}
func appendFile(path string, data []byte) error {
file, err := os.OpenFile(path, os.O_WRONLY|os.O_APPEND, 0755)
if err != nil {
return err
}
defer file.Close()
_, err = file.Write(data)
return err
}
func readFile(path string) ([]byte, error) {
return os.ReadFile(path)
}
func deleteFile(path string) error {
return os.Remove(path)
}
func fileStats(path string) (int64, time.Time, error) {
info, err := os.Stat(path)
if err != nil {
return -1, time.Time{}, err
}
size := info.Size()
modTime := info.ModTime()
return size, modTime, nil
}- function
fileStatsdigunakan untuk mendapatkan size dan modified time
Function ReadDir
- function
ReadDirdigunakan untuk melihat daftar files atau folder di directory tertentu - Menerima 1 argument:
namestring
- mengembalikan
[]DirEntrydan error: https://pkg.go.dev/os#DirEntry
package main
import (
"fmt"
"io"
"io/fs"
"os"
)
func main() {
newPath := "folder/file.txt"
copiedPath := "folder/copy.txt"
fmt.Println("Copy file", copyFile(newPath, copiedPath))
listedFiles, _ := listDir("./")
fmt.Println("", listedFiles)
}
func copyFile(srcPath, destPath string) error {
src, err := os.Open(srcPath)
if err != nil {
return err
}
defer src.Close()
dest, err := os.Create(destPath)
if err != nil {
return err
}
defer dest.Close()
_, err = io.Copy(dest, src)
if err != nil {
return err
}
return dest.Sync()
}
func listDir(path string) ([]fs.DirEntry, error) {
entries, err := os.ReadDir(path)
if err != nil {
return nil, err
}
listedFiles := make([]fs.DirEntry, 0)
for _, entry := range entries {
// kembalikan files, bukan folder
if !entry.IsDir() {
listedFiles = append(listedFiles, entry)
}
}
return listedFiles, nil
}- tambahkan validasi jika ingin mengembalikan files saja, bukan folder
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() // WAJIB di parse terlebih dahulu
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
Parse Flag
Flag harus di parse terlebih dahulu
Flag.NewFlagSet
flag.NewFlagSetdigunakan untuk membuat kumpulan flag khusus (FlagSet) yang terpisah dari flag default. Ini sangat penting saat kita membuat subcommand, seperti:
myapp serve --port=3000
myapp build --minifyflag.NewFlagSet(name string, errorHandling flag.ErrorHandling) *flag.FlagSetParameter:
nameNama dari subcommand / flagset (contoh:"serve","build").errorHandlingBagaimana FlagSet menangani error parsing:flag.ExitOnError→ keluar program bila ada errorflag.PanicOnError→ panicflag.ContinueOnError→ error dikembalikan ke caller
Contoh kasus:
package main
import (
"flag"
"fmt"
"os"
)
func main() {
if len(os.Args) < 2 {
fmt.Println("Commands:")
fmt.Println(" build Build the site")
fmt.Println(" serve Serve the site with hot reload")
os.Exit(1)
}
command := os.Args[1]
serveCmd := flag.NewFlagSet("serve", flag.ExitOnError)
servePort := serveCmd.Int("port", 3001, "application port")
dirContent := serveCmd.String("dir", "content", "directory content")
switch command {
case "serve", "server":
serveCmd.Parse(os.Args[2:])
fmt.Printf("Serving at http://localhost:%d\n", *servePort)
fmt.Println("Content dir:", *dirContent)
case "build":
serveCmd.Parse(os.Args[2:])
fmt.Println("Content dir:", *dirContent)
default:
fmt.Println("Unknown command:", command)
}
}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
| Function | Kegunaan |
|---|---|
| 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 ArdiansyahPackage 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
| Function | Kegunaan |
|---|---|
| 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
falsepackage 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
| Function | Kegunaan |
|---|---|
| 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
24Package 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
| Function | Kegunaan |
|---|---|
| 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 UTCDuration
- 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
intpackage 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
falsePackage 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
| Function | Kegunaan |
|---|---|
| regexp.MustCompile(string) | Membuat Regexp |
| Regexp.MatchString(string) bool | Mengecek 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
falsepackage 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))
}log
fmt dan log sama-sama bisa menampilkan teks ke output, tetapi keduanya dibuat untuk tujuan yang berbeda. Perbedaannya cukup penting, terutama dalam aplikasi besar.
fmtDipakai untuk formatted printing (mencetak teks biasa). Cocok untuk output umum, debugging ringan, atau tampilan CLI.logDipakai untuk structured application logging, dengan fitur tambahan yang membantu debugging dan error tracking.
log mendukung:
- Timestamp otomatis
- Level logging (walau versi default Go hanya Print / Fatal / Panic)
- Menulis ke file, buffer, atau writer lain menggunakan SetOutput
Bisa diarahkan ke file log
log bisa menulis ke file, bukan console:
file, _ := os.Create("app.log")
log.SetOutput(file)
log.Println("Server started")fmt tidak mendukung ini (harus manual menggunakan fmt.Fprintln(file, ...)).
Use-case terbaik
| Kebutuhan | Gunakan |
|---|---|
| Cetak output biasa untuk user | fmt |
| Debug cepat, print nilai | fmt |
| Logging aplikasi (server, CLI, engine) | log |
| Output error yang serius | log.Fatal / log.Panic |
| Menyimpan log ke file | log |
| Pipeline command (stdout/stderr separation) | log |
-
fmt- Dipakai untuk mencetak teks biasa
- Tanpa timestamp
- Tidak menandai level error
- Output ke stdout
-
log- Dipakai untuk logging aplikasi
- Ada timestamp + format khusus
- Bisa fatal/panic
- Output ke stderr
- Bisa diarahkan ke file/other writer
Package path
source::
-
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.gopackage 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.goFilepath.WalkDir
Fungsi filepath.WalkDir (atau filepath.Walk) adalah untuk melintasi (traverse) seluruh isi sebuah direktori secara rekursif, termasuk semua subdirektori dan filenya, untuk memproses setiap file dan folder yang ditemukan menggunakan fungsi callback yang disediakan, sangat berguna untuk mencari, menyalin, menghapus, atau memanipulasi file dalam jumlah besar di sebuah pohon direktori.
package content
import (
"fmt"
"geode/internal/config"
"io/fs"
"log"
"path/filepath"
"strings"
)
type FileEntry struct {
Path string
RelativePath string
Size int64
IsMarkdown bool
IsAsset bool
}
func GetAllMarkdownFilesAndAssets(srcDir string) []FileEntry {
var entries []FileEntry
// Load config
cfg, err := config.Load()
if err != nil {
log.Fatalf("Error loading config: %v", err)
}
ignorePatterns := cfg.IgnorePatterns
err = filepath.WalkDir(srcDir, func(path string, d fs.DirEntry, walkErr error) error {
if walkErr != nil {
fmt.Printf("Error accessing path %s: %v\n", path, walkErr)
return walkErr
}
if shouldSkip(path, ignorePatterns) {
if d.IsDir() {
return filepath.SkipDir
}
return nil
}
if d.IsDir() {
return nil
}
ext := strings.ToLower(filepath.Ext(path))
isMarkdown := ext == ".md" || ext == ".markdown"
isAsset := isAssetFile(ext)
if isMarkdown || isAsset {
rel, _ := filepath.Rel(srcDir, path)
entries = append(entries, FileEntry{
Path: path,
RelativePath: rel,
IsMarkdown: isMarkdown,
IsAsset: isAsset,
})
}
return nil
})
if err != nil {
log.Fatalf("Error during directory traversal: %v", err)
}
return entries
}
func shouldSkip(path string, patterns []string) bool {
lower := strings.ToLower(path)
for _, p := range patterns {
p = strings.ToLower(p)
if strings.Contains(lower, p) {
return true
}
}
return false
}
func isAssetFile(ext string) bool {
assetExt := map[string]bool{
// document
".pdf": true, ".csv": true,
// audio
".mp3": true, ".wav": true, ".ogg": true,
// video
".mp4": true, ".mov": true, ".webm": true,
// image
".png": true, ".jpg": true, ".jpeg": true, ".gif": true, ".svg": true, ".webp": true,
}
return assetExt[ext]
}parameter filepath.WalkDir :
path string- path lengkap ke file/dir saat ini.d fs.DirEntry- info dasar tentang entry (apakah file atau direktori, nama, dsb) tanpa melakukan os.Stat penuh (lebih efisien).walkErr error- error yang mungkin muncul saat mencoba membaca entry; jika non-nil harus ditangani.
Package io
source:: https://pkg.go.dev/io
reference:: https://www.youtube.com/watch?v=dqvvN0WXU_M
- 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
Function Copy
Copyberfungsi untuk copy file atau folderCopyMenerima 2 argument:- dest Interface Writer
- src Interface Reader
Copymengembalikan int64 dan error
package main
import (
"fmt"
"io"
"os"
)
func main() {
newPath := "folder/file.txt"
copiedPath := "folder/copy.txt"
fmt.Println("Copy file", copyFile(newPath, copiedPath))
}
func copyFile(srcPath, destPath string) error {
src, err := os.Open(srcPath)
if err != nil {
return err
}
defer src.Close()
dest, err := os.Create(destPath)
if err != nil {
return err
}
defer dest.Close()
// dest dan src bukan string melainkan interface
// destination dulu baru source, JANGAN KEBALIK
_, err = io.Copy(dest, src)
if err != nil {
return err
}
return dest.Sync()
}dest.Sync()Ini memastikan data benar-benar flush ke storage (berguna saat menulis file penting).
Copy
Argument jangan sampai kebalik, destination dulu baru source
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
- https://pkg.go.dev/
- go-blueprint untuk membuat struktur project go dengan mudah
- Golang Goldmark Package