Menu
CoddyTech

Pengantar Generics

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

Sebelum Go 1.18, menulis kode yang dapat digunakan kembali untuk berbagai tipe berarti harus menggandakan fungsi atau menggunakan interface kosong any dengan type assertion. Generics mengatasi masalah ini dengan memungkinkan kamu menulis fungsi dan tipe yang bekerja dengan beberapa tipe sekaligus, sambil tetap menjaga keamanan tipe sepenuhnya.

Misalkan kamu ingin mencari nilai minimum dalam sebuah slice. Tanpa generik, kamu memerlukan fungsi terpisah untuk setiap tipe:

func MinInt(values []int) int {
    min := values[0]
    for _, v := range values {
        if v < min {
            min = v
        }
    }
    return min
}

func MinFloat64(values []float64) float64 {
    min := values[0]
    for _, v := range values {
        if v < min {
            min = v
        }
    }
    return min
}

Dengan generics, kamu menulis logikanya sekali menggunakan parameter tipe di dalam tanda kurung siku:

func Min[T int | float64](values []T) T {
    min := values[0]
    for _, v := range values {
        if v < min {
            min = v
        }
    }
    return min
}

[T int | float64] mendeklarasikan parameter tipe T yang bisa berupa int atau float64. Sekarang kamu bisa memanggil Min([]int{3, 1, 2}) atau Min([]float64{3.5, 1.2}) dengan fungsi yang sama. Compiler memeriksa tipe saat kompilasi, jadi kamu mendapatkan keamanan tanpa overhead saat runtime.

Dalam pelajaran berikutnya, kita akan membahas parameter tipe, batasan, dan struct generik secara terperinci.

challenge icon

Tantangan

Mudah

Mari buat penganalisis skor yang dapat menangani skor bilangan bulat dan bilangan pecahan menggunakan generik! Kamu akan membuat satu fungsi generik yang dapat mencari nilai maksimum dalam sebuah slice, sehingga tidak perlu menulis kode duplikat untuk tipe numerik yang berbeda.

Kamu akan mengatur kodemu dalam dua file:

  • analyzer.go: Definisikan fungsi analisis generikmu.

    Buat fungsi generik Max[T int | float64](values []T) T yang mencari dan mengembalikan nilai maksimum dalam sebuah slice. Fungsi ini harus dapat bekerja dengan tipe int dan float64 melalui parameter tipe T.

    Buat juga fungsi generik Sum[T int | float64](values []T) T yang menghitung dan mengembalikan jumlah semua nilai dalam sebuah slice.

  • main.go: Baca input dan tunjukkan fungsi generikmu dengan tipe yang berbeda.

    Baca penanda tipe (int atau float), lalu baca jumlah nilai dan nilai sebanyak jumlah tersebut. Parse nilai sesuai tipenya, panggil Max dan Sum dengan tipe yang sesuai, lalu cetak hasilnya.

    Untuk input bilangan bulat, cetak:

    Max (int): [value]
    Sum (int): [value]

    Untuk input bilangan pecahan, cetak dengan satu angka di belakang koma:

    Max (float): [value]
    Sum (float): [value]

Input berikut akan diberikan:

  • Baris 1: Penanda tipe (int atau float)
  • Baris 2: Jumlah nilai (bilangan bulat)
  • Baris berikutnya: Satu nilai per baris

Contohnya, jika diberikan:

int
4
15
8
23
11

Outputmu harus berupa:

Max (int): 23
Sum (int): 57

Dan jika diberikan:

float
3
4.5
9.2
6.8

Outputmu harus berupa:

Max (float): 9.2
Sum (float): 20.5

Perhatikan bahwa fungsi generik yang sama menangani data bilangan bulat dan bilangan pecahan: parameter tipe [T int | float64] memungkinkan compiler menghasilkan kode yang aman dari segi tipe untuk setiap penggunaan, sementara kamu hanya perlu menulis logikanya sekali.

Coba sendiri

package main

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

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

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

	// Baca jumlahnya
	countStr, _ := reader.ReadString('\n')
	count, _ := strconv.Atoi(strings.TrimSpace(countStr))

	if typeStr == "int" {
		// Baca nilai integer
		values := make([]int, count)
		for i := 0; i < count; i++ {
			line, _ := reader.ReadString('\n')
			values[i], _ = strconv.Atoi(strings.TrimSpace(line))
		}

		// TODO: Panggil Max dan Sum dengan slice integer
		// TODO: Cetak hasil dalam format "Max (int): [value]" dan "Sum (int): [value]"

	} else if typeStr == "float" {
		// Baca nilai float
		values := make([]float64, count)
		for i := 0; i < count; i++ {
			line, _ := reader.ReadString('\n')
			values[i], _ = strconv.ParseFloat(strings.TrimSpace(line), 64)
		}

		// TODO: Panggil Max dan Sum dengan slice float64
		// TODO: Cetak hasil dengan satu angka di belakang koma dalam format "Max (float): [value]" dan "Sum (float): [value]"
	}
}
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