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.
Tantangan
MudahMari 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) Tyang menemukan dan mengembalikan nilai maksimum dalam slice. Fungsi ini harus bekerja dengan tipeintdanfloat64melalui parameter tipeT.Buat juga fungsi generik
Sum[T int | float64](values []T) Tyang menghitung dan mengembalikan jumlah semua nilai dalam slice.main.go: Baca input dan tunjukkan fungsi generikmu dengan tipe yang berbeda.Baca indikator tipe (
intataufloat), lalu baca jumlah nilai diikuti nilai sebanyak itu. Uraikan nilai sesuai tipenya, panggilMaxdanSumdengan 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 (
intataufloat) - Baris 2: Jumlah nilai (bilangan bulat)
- Baris berikutnya: Satu nilai di setiap baris
Contohnya, jika diberikan:
int
4
15
8
23
11Outputmu seharusnya:
Max (int): 23
Sum (int): 57Dan jika diberikan:
float
3
4.5
9.2
6.8Outputmu seharusnya:
Max (float): 9.2
Sum (float): 20.5Perhatikan 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]"
}
}
Pelajaran ini berisi kuis singkat. Mulai pelajarannya untuk menjawab kuis dan melacak progresmu.
Semua pelajaran di Pemrograman Berorientasi Objek
1Dasar-Dasar OOP di Go
File EksternalWorkspace Go dan modulePaket dan ImporNama yang Diekspor dan Tidak DieksporPengantar OOP di Gostruct sebagai classMendefinisikan method pada structPointer receiver vs value receiverInisialisasi structFungsi KonstruktorUlasan: Kalkulator Sederhana4Interface
Pengenalan InterfaceImplementasi ImplisitInterface sebagai KontrakInterface Kosong (any)Type AssertionType SwitchKomposisi InterfaceInterface Stringer & ErrorUlasan: Kalkulator Bentuk7Enkapsulasi
Field yang Diekspor vs Tidak DieksporEnkapsulasi Tingkat PackageMethod Getter dan SetterPenyembunyian Informasi di GoRingkasan: Data Siswa10Generics (Go 1.18+)
Pengantar GenericsParameter TipeBatasan TipeStruct GenerikCara Alternatif untuk Method GenerikRingkasan Koleksi Generik2Mendalami Tipe dan Struct
Tipe Dasar dan KompositDefinisi Tipe KustomTag StructStruct AnonimStruct BersarangNilai Nol dan Nilai BawaanRangkuman: Buku Kontak5Komposisi daripada Pewarisan
Mengapa Go Tidak Memiliki PewarisanDasar Penyematan StructPromosi methodMenyematkan Beberapa StructPenyematan vs AgregasiMembayangi method yang DisematkanRangkuman: Hierarki Karyawan8Penanganan Error & OOP
Interface errorTipe Error KustomPembungkusan Error (fmt.Errorf)Error Sentinelerrors.Is() dan errors.As()Panic, Defer, dan RecoverRangkuman: Parser File3Pointer dan Memori
Dasar-Dasar Pointer di GoPointer ke StructPass by Value vs ReferenceFungsi new()Garbage Collection di GoRekap: Pembuat Linked List6Polimorfisme di Go
Polimorfisme melalui InterfaceDuck Typing di GoAturan Pemenuhan InterfaceKoleksi PolimorfikInjeksi DependensiRangkuman: Pemroses Pembayaran9Konkruensi & OOP
Dasar-dasar GoroutineChannel & KomunikasiChannel Ber-buffer vs Tanpa BufferPernyataan selectsync.Mutex & sync.RWMutexsync.WaitGroupDesain Struct yang Aman untuk ThreadRingkasan: Worker PoolLatihan sendiri: Compiler Go online