BAB 8: Konstanta

Memahami penggunaan konstanta di Go untuk menyimpan nilai yang tidak berubah. Belajar deklarasi const, multi konstanta, dan best practices penggunaan konstanta.

Setelah mempelajari variable dan data types, sekarang kita akan belajar tentang konstanta. Konstanta adalah nilai yang tidak berubah sepanjang program berjalan. Berbeda dengan variable yang nilainya bisa diubah-ubah, konstanta nilainya tetap dari awal sampai akhir program.

Apa itu Konstanta?

Konstanta adalah jenis variable yang nilainya tidak bisa diubah setelah dideklarasikan. Bayangkan konstanta seperti nama kamu - sekali ditentukan, ya tetap begitu. Konstanta sangat berguna untuk menyimpan nilai-nilai yang memang tidak akan berubah, seperti nilai pi (3.14159), kecepatan cahaya, atau konfigurasi aplikasi.

Perbedaan utama konstanta dengan variable:

  • Variable: nilainya bisa berubah (var)
  • Konstanta: nilainya tetap selamanya (const)

Deklarasi Konstanta Dasar

Cara mendeklarasikan konstanta sama seperti variable, tapi menggunakan keyword const:

package main

import "fmt"

func main() {
    const firstName string = "John"
    const pi float64 = 3.14159
    const isActive bool = true
    
    fmt.Println("Nama:", firstName)
    fmt.Println("Pi:", pi)
    fmt.Println("Status:", isActive)
}

Type Inference pada Konstanta

Sama seperti variable, konstanta juga mendukung type inference - Go bisa menebak type data berdasarkan nilai yang diberikan:

package main

import "fmt"

func main() {
    const lastName = "Wick"           // string
    const gravity = 9.81              // float64
    const maxUsers = 100              // int
    const isReady = true              // bool
    
    fmt.Printf("lastName: %s (type: %T)\n", lastName, lastName)
    fmt.Printf("gravity: %.2f (type: %T)\n", gravity, gravity)
    fmt.Printf("maxUsers: %d (type: %T)\n", maxUsers, maxUsers)
    fmt.Printf("isReady: %t (type: %T)\n", isReady, isReady)
}

Deklarasi Multiple Konstanta

Konstanta dalam Satu Baris

package main

import "fmt"

func main() {
    const satu, dua = 1, 2
    const three, four string = "tiga", "empat"
    
    fmt.Println("satu:", satu, "dua:", dua)
    fmt.Println("three:", three, "four:", four)
}

Grouped Constants

Untuk organisasi yang lebih baik, kita bisa mengelompokkan konstanta menggunakan kurung:

package main

import "fmt"

func main() {
    const (
        square     = "kotak"
        isToday    bool = true
        numeric    uint8 = 1
        floatNum   = 2.2
    )
    
    fmt.Println("Shape:", square)
    fmt.Println("Today:", isToday)
    fmt.Println("Number:", numeric)
    fmt.Println("Float:", floatNum)
}

Konstanta dengan Nilai yang Sama

Ketika kita tidak menuliskan nilai dalam deklarasi konstanta, Go akan menggunakan nilai yang sama dengan konstanta di atasnya:

package main

import "fmt"

func main() {
    const (
        a = "konstanta"
        b                    // b akan sama dengan a: "konstanta"
        c = "berbeda"
        d                    // d akan sama dengan c: "berbeda"
    )
    
    fmt.Println("a:", a)     // konstanta
    fmt.Println("b:", b)     // konstanta
    fmt.Println("c:", c)     // berbeda
    fmt.Println("d:", d)     // berbeda
}

Kombinasi Berbagai Deklarasi

package main

import "fmt"

func main() {
    const (
        today string = "senin"
        sekarang               // "senin" (sama dengan today)
        isToday2 = true        // type inference untuk bool
        tomorrow               // true (sama dengan isToday2)
    )
    
    fmt.Println("today:", today)
    fmt.Println("sekarang:", sekarang)
    fmt.Println("isToday2:", isToday2)
    fmt.Println("tomorrow:", tomorrow)
}

Konstanta untuk Konfigurasi Aplikasi

Konstanta sangat berguna untuk menyimpan konfigurasi aplikasi:

package main

import "fmt"

const (
    AppName    = "My Go App"
    Version    = "1.0.0"
    MaxUsers   = 1000
    TimeoutSec = 30
    DebugMode  = true
)

func main() {
    fmt.Printf("Starting %s v%s\n", AppName, Version)
    fmt.Printf("Max users: %d\n", MaxUsers)
    fmt.Printf("Timeout: %d seconds\n", TimeoutSec)
    fmt.Printf("Debug mode: %t\n", DebugMode)
}

Konstanta Matematika

package main

import "fmt"

const (
    Pi         = 3.14159265359
    E          = 2.71828182846
    GoldenRatio = 1.61803398875
    SqrtTwo    = 1.41421356237
)

func calculateCircleArea(radius float64) float64 {
    return Pi * radius * radius
}

func main() {
    radius := 5.0
    area := calculateCircleArea(radius)
    
    fmt.Printf("Circle area with radius %.1f: %.2f\n", radius, area)
    fmt.Printf("Pi: %.5f\n", Pi)
    fmt.Printf("Euler's number: %.5f\n", E)
}

Konstanta String untuk Enum-like Values

Meskipun Go tidak memiliki enum seperti bahasa lain, kita bisa menggunakan konstanta string untuk hal serupa:

package main

import "fmt"

const (
    StatusPending   = "pending"
    StatusApproved  = "approved"
    StatusRejected  = "rejected"
    StatusCompleted = "completed"
)

func processOrder(status string) {
    switch status {
    case StatusPending:
        fmt.Println("Order is waiting for approval")
    case StatusApproved:
        fmt.Println("Order has been approved")
    case StatusRejected:
        fmt.Println("Order has been rejected")
    case StatusCompleted:
        fmt.Println("Order has been completed")
    default:
        fmt.Println("Unknown status")
    }
}

func main() {
    processOrder(StatusPending)
    processOrder(StatusApproved)
    processOrder("invalid")
}

Konstanta vs Variable

Mari lihat perbedaan praktis antara konstanta dan variable:

package main

import "fmt"

func main() {
    // Variable - bisa diubah
    var name string = "John"
    fmt.Println("Original name:", name)
    
    name = "Jane"  // OK - variable bisa diubah
    fmt.Println("Updated name:", name)
    
    // Konstanta - tidak bisa diubah
    const companyName = "Tech Corp"
    fmt.Println("Company:", companyName)
    
    // companyName = "New Corp"  // ERROR! Konstanta tidak bisa diubah
    
    // Konstanta harus diinisialisasi saat deklarasi
    // const uninitialized  // ERROR! Konstanta harus ada nilainya
}

Scope Konstanta

Konstanta mengikuti aturan scope yang sama dengan variable:

package main

import "fmt"

// Global constants
const (
    GlobalAppName = "My App"
    GlobalVersion = "1.0"
)

func processData() {
    // Local constants
    const (
        ProcessTimeout = 30
        MaxRetries     = 3
    )
    
    fmt.Printf("Processing with timeout: %d seconds\n", ProcessTimeout)
    fmt.Printf("Max retries: %d\n", MaxRetries)
    fmt.Printf("App: %s v%s\n", GlobalAppName, GlobalVersion)
}

func main() {
    processData()
    
    // Konstanta dalam block
    if true {
        const localMessage = "Hello from block"
        fmt.Println(localMessage)
    }
    
    // fmt.Println(localMessage)  // ERROR! localMessage tidak ada di scope ini
}

Konstanta untuk HTTP Status Codes

Contoh praktis penggunaan konstanta untuk HTTP status codes:

package main

import "fmt"

const (
    StatusOK                   = 200
    StatusBadRequest          = 400
    StatusUnauthorized        = 401
    StatusForbidden           = 403
    StatusNotFound            = 404
    StatusInternalServerError = 500
)

func handleResponse(statusCode int) {
    switch statusCode {
    case StatusOK:
        fmt.Println("Request successful")
    case StatusBadRequest:
        fmt.Println("Bad request")
    case StatusUnauthorized:
        fmt.Println("Authentication required")
    case StatusNotFound:
        fmt.Println("Resource not found")
    case StatusInternalServerError:
        fmt.Println("Server error")
    default:
        fmt.Printf("Status code: %d\n", statusCode)
    }
}

func main() {
    handleResponse(StatusOK)
    handleResponse(StatusNotFound)
    handleResponse(StatusInternalServerError)
}

Konstanta untuk Database Configuration

package main

import "fmt"

const (
    // Database constants
    DBHost     = "localhost"
    DBPort     = 5432
    DBName     = "myapp_db"
    DBUser     = "admin"
    DBPassword = "secret123"
    
    // Connection pool constants
    MaxOpenConns    = 25
    MaxIdleConns    = 25
    ConnMaxLifetime = 300 // seconds
)

func createConnectionString() string {
    return fmt.Sprintf("host=%s port=%d dbname=%s user=%s password=%s",
        DBHost, DBPort, DBName, DBUser, DBPassword)
}

func main() {
    connStr := createConnectionString()
    fmt.Println("Connection string:", connStr)
    fmt.Printf("Max connections: %d\n", MaxOpenConns)
    fmt.Printf("Max idle connections: %d\n", MaxIdleConns)
}

Konstanta dalam Package Level

Konstanta juga bisa dideklarasikan di level package (di luar function):

package main

import "fmt"

// Package level constants
const (
    AppTitle       = "My Golang Application"
    DefaultTimeout = 30
    MaxFileSize    = 1024 * 1024 * 10 // 10MB
)

func uploadFile(size int) {
    if size > MaxFileSize {
        fmt.Printf("File too large. Max size: %d bytes\n", MaxFileSize)
        return
    }
    fmt.Printf("Uploading file of size: %d bytes\n", size)
}

func main() {
    fmt.Printf("Welcome to %s\n", AppTitle)
    fmt.Printf("Default timeout: %d seconds\n", DefaultTimeout)
    
    uploadFile(1024)           // OK
    uploadFile(MaxFileSize + 1) // Too large
}

Best Practices

1. Gunakan Nama yang Deskriptif

// BAIK
const (
    MaxRetryAttempts = 3
    ConnectionTimeout = 30
    DefaultPageSize = 20
)

// KURANG BAIK
const (
    M = 3
    T = 30
    P = 20
)

2. Kelompokkan Konstanta yang Berkaitan

// BAIK: kelompokkan berdasarkan kategori
const (
    // HTTP Status Codes
    StatusOK = 200
    StatusNotFound = 404
    StatusError = 500
)

const (
    // Database Configuration
    DBTimeout = 30
    DBMaxConns = 10
    DBRetries = 3
)

// KURANG BAIK: semua dicampur
const (
    StatusOK = 200
    DBTimeout = 30
    StatusNotFound = 404
    DBMaxConns = 10
)

3. Gunakan Konstanta untuk Magic Numbers

// BAIK: gunakan konstanta
const (
    DaysInWeek = 7
    HoursInDay = 24
    MinutesInHour = 60
)

func calculateWeeklyHours(dailyHours int) int {
    return dailyHours * DaysInWeek
}

// KURANG BAIK: magic numbers
func calculateWeeklyHours(dailyHours int) int {
    return dailyHours * 7  // 7 itu apa?
}

4. Gunakan Type yang Tepat

// BAIK: type yang sesuai
const (
    ServerPort    uint16  = 8080    // port number
    MaxUsers      int     = 1000    // jumlah user
    TimeoutSec    float64 = 30.5    // timeout dalam detik
    IsProduction  bool    = false   // flag environment
)

Latihan

Latihan 1: Konstanta Dasar

package main

import "fmt"

func main() {
    // TODO: Buat konstanta untuk:
    // - nama lengkap kamu (string)
    // - umur kamu (int) 
    // - tinggi badan dalam meter (float64)
    // - status pelajar (bool)
    
    // Tampilkan semua konstanta dengan format yang rapi
}

Latihan 2: Konstanta Matematika

package main

import "fmt"

// TODO: Buat konstanta untuk:
// - Pi (3.14159)
// - Gravitasi bumi (9.81 m/s²)
// - Kecepatan cahaya (299792458 m/s)

// TODO: Buat function untuk menghitung:
// - Luas lingkaran berdasarkan radius
// - Kecepatan jatuh bebas berdasarkan waktu
// - Jarak yang ditempuh cahaya dalam waktu tertentu

func main() {
    // Test semua function yang sudah dibuat
}

Latihan 3: Konstanta untuk Status

package main

import "fmt"

// TODO: Buat konstanta untuk status order:
// - "draft", "submitted", "processing", "shipped", "delivered", "cancelled"

// TODO: Buat function processOrder(status string) yang:
// - Menerima status sebagai parameter
// - Menampilkan pesan sesuai status
// - Menggunakan switch case

func main() {
    // TODO: Test function dengan berbagai status
}

Latihan 4: Konfigurasi Aplikasi

package main

import "fmt"

// TODO: Buat konstanta untuk konfigurasi web server:
// - Server host (localhost)
// - Server port (8080)
// - Max connections (100)
// - Request timeout (30 detik)
// - Static files directory ("/static")

// TODO: Buat function startServer() yang menampilkan info server
// TODO: Buat function isValidConnection(current int) yang cek apakah 
//       jumlah koneksi saat ini melebihi batas maksimal

func main() {
    // Test semua function
}

Kesimpulan

Konstanta adalah fitur penting di Go untuk menyimpan nilai yang tidak berubah. Poin-poin penting yang perlu diingat:

  • Gunakan const untuk mendeklarasikan konstanta
  • Konstanta harus diinisialisasi saat deklarasi
  • Nilai konstanta tidak bisa diubah setelah dideklarasikan
  • Konstanta mendukung type inference
  • Bisa mendeklarasikan multiple konstanta sekaligus
  • Konstanta tanpa nilai akan mengikuti nilai konstanta di atasnya
  • Gunakan konstanta untuk magic numbers, konfigurasi, dan nilai tetap
  • Kelompokkan konstanta yang berkaitan untuk organisasi yang lebih baik

Dengan memahami konstanta, kamu bisa membuat kode yang lebih aman dan mudah dipelihara. Nilai-nilai yang memang tidak akan berubah sebaiknya dideklarasikan sebagai konstanta untuk mencegah kesalahan dan membuat kode lebih readable. Di bab selanjutnya, kita akan belajar tentang operator untuk memanipulasi data.