Menu
CoddyTech

Dasar-Dasar Reflection

Termasuk bagian Pemrograman Berorientasi Objek dalam perjalanan GO di Coddy. Pelajaran 83 dari 107.

Refleksi memungkinkan program memeriksa dan memanipulasi strukturnya sendiri saat runtime. Package reflect Go menyediakan kemampuan ini, sehingga kamu dapat memeriksa tipe, membaca field struct, dan memanggil method secara dinamis.

Dua tipe inti dalam refleksi adalah reflect.Type dan reflect.Value. Kamu mendapatkannya menggunakan reflect.TypeOf() dan reflect.ValueOf():

import "reflect"

type Person struct {
    Name string
    Age  int
}

p := Person{Name: "Alice", Age: 30}

t := reflect.TypeOf(p)
v := reflect.ValueOf(p)

fmt.Println(t.Name())       // Person
fmt.Println(t.Kind())       // struct
fmt.Println(v.NumField())   // 2

Kamu bisa melakukan iterasi pada field struct untuk memeriksa nama, tipe, dan nilainya:

for i := 0; i < t.NumField(); i++ {
    field := t.Field(i)
    value := v.Field(i)
    fmt.Printf("%s: %v\n", field.Name, value)
}
// Output:
// Name: Alice
// Age: 30

Reflection sangat kuat, tetapi memiliki konsekuensi: reflection melewati pemeriksaan tipe saat kompilasi, berjalan lebih lambat daripada akses langsung, dan membuat kode lebih sulit dipahami. Gunakan secukupnya untuk tugas seperti marshaling JSON, pemetaan ORM, atau membangun utilitas generik saat tipe tidak diketahui pada waktu kompilasi.

challenge icon

Tantangan

Mudah

Mari buat inspector struct yang menggunakan reflection untuk memeriksa struct apa pun dan melaporkan strukturnya! Ini adalah contoh penggunaan reflection yang praktis: membuat utilitas yang bekerja dengan tipe yang tidak diketahui saat compile.

Kamu akan mengatur kodemu dalam dua file:

  • inspector.go: Buat utilitas pemeriksaan berbasis reflection.

    Buat fungsi InspectStruct(v any) string yang menggunakan package reflect untuk memeriksa struct apa pun yang diberikan kepadanya. Fungsi ini harus mengembalikan laporan berformat yang berisi:

    • Nama tipe struct
    • Kind struct (seharusnya "struct")
    • Jumlah field
    • Untuk setiap field: nama field, tipenya, dan nilai saat ini

    Format output-nya harus seperti berikut:

    Type: [TypeName]
    Kind: struct
    Fields: [count]
    - [FieldName] ([FieldType]): [Value]
    - [FieldName] ([FieldType]): [Value]
    ...

    Gunakan reflect.TypeOf() untuk mendapatkan informasi tipe dan reflect.ValueOf() untuk mengakses nilai field. Lakukan perulangan pada field menggunakan NumField(), Field(i) pada tipe untuk mendapatkan metadata, dan Field(i) pada nilai untuk mendapatkan nilai sebenarnya.

  • main.go: Definisikan struct contoh dan gunakan inspector-mu.

    Baca tipe struct (product atau employee) dan nilai field-nya, lalu buat struct yang sesuai dan periksa struct tersebut.

    Untuk product: Buat struct Product dengan field Name (string), Price (float64), dan InStock (bool). Baca nama, harga, dan status stok.

    Untuk employee: Buat struct Employee dengan field ID (int), Name (string), dan Department (string). Baca ID, nama, dan departemen.

    Berikan struct yang dibuat ke InspectStruct dan cetak hasilnya.

Input berikut akan diberikan:

  • Baris 1: Tipe struct (product atau employee)
  • Baris berikutnya: Nilai field untuk tipe struct tersebut

Contohnya, jika diberikan:

product
Laptop
999.99
true

Output-mu seharusnya:

Type: Product
Kind: struct
Fields: 3
- Name (string): Laptop
- Price (float64): 999.99
- InStock (bool): true

Dan jika diberikan:

employee
42
Alice Johnson
Engineering

Output-mu seharusnya:

Type: Employee
Kind: struct
Fields: 3
- ID (int): 42
- Name (string): Alice Johnson
- Department (string): Engineering

Dan jika diberikan:

product
Headphones
79.50
false

Output-mu seharusnya:

Type: Product
Kind: struct
Fields: 3
- Name (string): Headphones
- Price (float64): 79.5
- InStock (bool): false

Perhatikan bagaimana inspectormu bekerja dengan berbagai tipe struct tanpa mengetahui strukturnya terlebih dahulu. Inilah kekuatan reflection! Fungsi InspectStruct yang sama menangani struct Product dan Employee secara dinamis.

Coba sendiri

package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
	"strings"
)

// Struct Product dengan field Name, Price, dan InStock
type Product struct {
	Name    string
	Price   float64
	InStock bool
}

// Struct Employee dengan field ID, Name, dan Department
type Employee struct {
	ID         int
	Name       string
	Department string
}

func main() {
	reader := bufio.NewReader(os.Stdin)

	// Baca tipe struct
	structType, _ := reader.ReadString('\n')
	structType = strings.TrimSpace(structType)

	if structType == "product" {
		// Baca field produk
		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		priceStr, _ := reader.ReadString('\n')
		priceStr = strings.TrimSpace(priceStr)
		price, _ := strconv.ParseFloat(priceStr, 64)

		inStockStr, _ := reader.ReadString('\n')
		inStockStr = strings.TrimSpace(inStockStr)
		inStock, _ := strconv.ParseBool(inStockStr)

		// TODO: Buat struct Product dengan nilai yang telah dibaca
		// TODO: Panggil InspectStruct dengan produk tersebut dan cetak hasilnya

	} else if structType == "employee" {
		// Baca field karyawan
		idStr, _ := reader.ReadString('\n')
		idStr = strings.TrimSpace(idStr)
		id, _ := strconv.Atoi(idStr)

		name, _ := reader.ReadString('\n')
		name = strings.TrimSpace(name)

		department, _ := reader.ReadString('\n')
		department = strings.TrimSpace(department)

		// TODO: Buat struct Employee dengan nilai yang telah dibaca
		// TODO: Panggil InspectStruct dengan karyawan tersebut dan cetak hasilnya

	}
}
quiz iconUji dirimu

Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.

Semua pelajaran di Pemrograman Berorientasi Objek

Latihan sendiri: Compiler Go online