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 kamu harus menggandakan fungsi atau menggunakan interface kosong any dengan assertion tipe. Generics mengatasi masalah ini dengan memungkinkan kamu menulis fungsi dan tipe yang dapat bekerja dengan beberapa tipe sekaligus sambil tetap menjaga keamanan tipe sepenuhnya.

Pertimbangkan cara mencari nilai minimum dalam slice. Tanpa generik, kamu perlu 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 generik, kamu menulis logika 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, sehingga kamu mendapatkan keamanan tanpa overhead saat runtime.

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

challenge icon

Tantangan

Mudah

Mari buat penganalisis skor yang dapat menangani skor bilangan bulat dan floating-point menggunakan generik! Kamu akan membuat satu fungsi generik yang dapat menemukan nilai maksimum dalam 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 menemukan dan mengembalikan nilai maksimum dalam slice. Fungsi ini harus 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 slice.

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

    Baca indikator tipe (int atau float), lalu baca jumlah nilai diikuti nilai sebanyak itu. Uraikan 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 float, cetak dengan satu angka di belakang koma:

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

Input yang diberikan adalah sebagai berikut:

  • Baris 1: Indikator tipe (int atau float)
  • Baris 2: Jumlah nilai (bilangan bulat)
  • Baris berikutnya: Satu nilai di setiap baris

Contohnya, jika diberikan:

int
4
15
8
23
11

Outputmu seharusnya:

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

Dan jika diberikan:

float
3
4.5
9.2
6.8

Outputmu seharusnya:

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

Perhatikan bagaimana fungsi generik yang sama menangani data bilangan bulat dan floating-point: parameter tipe [T int | float64] memungkinkan compiler menghasilkan kode yang aman dari kesalahan tipe untuk setiap penggunaan, sementara kamu hanya perlu menulis logikanya satu kali.

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