Memahami Visibilitas Pada Go

Di Go, tidak ada istilah “Public”, “Protected”, dan “Private” untuk mengatur hak akses pada properti atau metode. Yang ada adalah istilah “Exported” dan “Unexported”.

Secara sederhana, “Exported” berarti properti atau metode yang dapat digunakan oleh package lain, sedangkan “Unexported” tidak dapat digunakan oleh package lain.

Ini berbeda dengan OOP PHP dan Java yang menggunakan tiga istilah tersebut. Untuk mengatur visibilitas dalam Go, digunakan format kapitalisasi dan non-kapitalisasi.

  • Capitalized identifiers Identifier yang diawali huruf kapital merupakan exported. Jika sebuah properti atau metode diawali dengan huruf kapital, maka properti atau metode tersebut adalah exported dan dapat digunakan di luar package.
  • Non-capitalized identifiers Identifier yang tidak diawali huruf kapital merupakan unexported. Jika sebuah properti atau metode diawali dengan huruf kecil, maka properti atau metode tersebut adalah unexported dan tidak dapat digunakan di luar package.

Biasanya, visibilitas ini digunakan saat mendeklarasikan struct, field struct, atau metode. Jika nama sebuah struct diawali dengan huruf kapital, maka struct tersebut adalah exported dan dapat digunakan oleh package lain. Hal ini juga berlaku untuk field struct.

Sebagai contoh, mari kita buat dua file, pertama adalah entity.go, dan kedua adalah main.go.

// entity.go
package main

type Book struct {
    Title    string
    quantity int
}

type person struct {
    //
}

func (b *Book) GetTitle() string {
    return b.Title
}

func (b *Book) getQuantity() int {
    return b.quantity
}

Pada kode di atas, kita mendeklarasikan struct Book dengan satu field struct yang diawali huruf kecil yaitu quantity.

Kemudian ada struct lain bernama person yang diawali huruf kecil dan tidak memiliki field struct.

Kita juga menggunakan receiver method untuk mendefinisikan dua metode pada struct Book, yaitu GetTitle() dengan huruf awal kapital, dan getQuantity() dengan huruf awal kecil.

// main.go
package main

import "fmt"

type Book struct {
    Title    string
    quantity int
}

type person struct {
    //
}

func (b *Book) GetTitle() string {
    return b.Title
}

func (b *Book) getQuantity() int {
    return b.quantity
}

func main() {
    book1 := &Book{
        Title:    "Book 1",
        quantity: 2,
    }

    fmt.Println("Book 1 :", book1)
    fmt.Println("Book 1 Name :", book1.GetTitle())
    fmt.Println("Book 1 Quantity :", book1.getQuantity())

    var person person
    fmt.Println("Person :", &person)
}

Image 1

Dari kode di atas, saat dijalankan dalam satu package yang sama, tidak akan ada masalah. Namun, jika dijalankan dalam file yang berbeda, apa yang akan terjadi? Mari kita lihat.

Mari kita pisahkan ke dalam file yang berbeda, sekarang buat file baru bernama main.go. Isinya akan menggunakan struct Book dan person dari package entity.

Jangan lupa untuk menginisialisasi modul dengan menggunakan perintah go mod init visibility.

// entity.go
package entity

import "fmt"

type Book struct {
    Title    string
    quantity int
}

type person struct {
    //
}

func (b *Book) GetTitle() string {
    return b.Title
}

func (b *Book) getQuantity() int {
    return b.quantity
}
// main.go
package main

import (
    "fmt"
    "visibility/entity"
)

func main() {
    book1 := &entity.Book{
        Title:    "Book 1",
        quantity: 2,
    }

    fmt.Println("Book 1 :", book1)
    fmt.Println("Book 1 Name :", book1.GetTitle())
    fmt.Println("Book 1 Quantity :", book1.getQuantity())

    var person entity.person
    fmt.Println("Person :", &person)
}

Image 2

Apa yang terjadi jika kode di atas dijalankan? Ketika dijalankan, akan muncul error seperti di bawah ini:

# command-line-arguments
.\main.go:11:3: cannot refer to unexported field 'quantity' in struct literal of type entity.Book
.\main.go:16:40: book1.getQuantity undefined (cannot refer to unexported field or method getQuantity)
.\main.go:18:13: cannot refer to unexported name entity.person

Dari error di atas, terlihat bahwa struct, field struct, maupun metode yang unexported tidak dapat digunakan oleh package lain.