Menu
CoddyTech

Duck Typing di Go

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

Istilah duck typing berasal dari ungkapan: "Jika ia berjalan seperti bebek dan bersuara seperti bebek, maka ia adalah bebek." Dalam Go, ini berarti tipe tidak perlu secara eksplisit menyatakan bahwa tipe tersebut mengimplementasikan interface. Tipe itu hanya perlu memiliki method yang tepat.

Perhatikan interface ini dan dua tipe yang sama sekali tidak berkaitan:

type Quacker interface {
    Quack() string
}

type Duck struct{}
func (d Duck) Quack() string { return "Quack!" }

type Robot struct{}
func (r Robot) Quack() string { return "Beep-quack!" }

Baik Duck maupun Robot tidak menyebutkan Quacker di mana pun dalam definisinya. Namun, keduanya memenuhi antarmuka hanya karena memiliki method Quack() dengan tanda tangan yang tepat:

func MakeItQuack(q Quacker) {
    fmt.Println(q.Quack())
}

func main() {
    MakeItQuack(Duck{})   // Quack!
    MakeItQuack(Robot{})  // Beep-quack!
}

Kesesuaian implisit ini sangat berguna karena memungkinkan kamu mendefinisikan interface setelah tipe-tipe tersebut sudah ada. Kamu bisa membuat interface yang cocok dengan tipe dari package eksternal tanpa mengubah kode sumbernya. Tipe-tipe tersebut tidak perlu mengetahui interface-mu. Tipe-tipe itu hanya perlu berperilaku dengan benar.

Duck typing di Go memberimu fleksibilitas seperti pada bahasa dinamis sekaligus mempertahankan keamanan tipe saat kompilasi. Kompilator memverifikasi bahwa tipe benar-benar memiliki method yang diperlukan sebelum mengizinkannya digunakan sebagai nilai interface.

challenge icon

Tantangan

Mudah

Mari buat sistem pesan yang menunjukkan duck typing dalam praktik. Kamu akan membuat tipe-tipe yang sama sekali tidak berhubungan, tetapi semuanya dapat mengirim pesan melalui antarmuka yang sama, tanpa secara eksplisit menyatakan bahwa mereka mengimplementasikannya.

Kamu akan membagi kodemu ke dalam tiga file:

  • messengers.go: Buat tiga struct yang tidak berhubungan, tetapi memiliki perilaku yang sama:
    • Phone dengan field Number. method SendMessage(text string) string-nya mengembalikan SMS to [Number]: [text]
    • Computer dengan field Email. method SendMessage(text string) string-nya mengembalikan Email to [Email]: [text]
    • Pigeon dengan field Name. method SendMessage(text string) string-nya mengembalikan [Name] carries: [text]
    Perhatikan bahwa tidak satu pun dari tipe ini menyebut antarmuka. Mereka hanya kebetulan memiliki tanda tangan method yang sama.
  • sender.go: Definisikan antarmuka Messenger yang memerlukan method SendMessage(text string) string. Buat fungsi bernama Broadcast yang menerima slice berisi Messenger dan string pesan, lalu mengembalikan slice berisi string yang memuat hasil pemanggilan SendMessage pada setiap messenger.
  • main.go: Baca detail dari input, buat masing-masing satu dari setiap tipe messenger, kumpulkan semuanya ke dalam slice berisi Messenger, lalu gunakan Broadcast untuk mengirim pesan melalui semuanya. Cetak setiap hasil pada barisnya sendiri.

Input berikut akan diberikan:

  • Baris 1: Nomor telepon
  • Baris 2: Alamat email
  • Baris 3: Nama merpati
  • Baris 4: Pesan untuk disebarkan

Misalnya, jika diberikan 555-1234, alice@mail.com, Winston, dan Hello World, output-mu seharusnya:

SMS to 555-1234: Hello World
Email to alice@mail.com: Hello World
Winston carries: Hello World

Inti utamanya adalah Phone, Computer, dan Pigeon tidak memiliki kesamaan. Mereka tidak berbagi tipe dasar atau secara eksplisit mengimplementasikan Messenger. Namun, karena semuanya "berkwek" dengan cara yang sama (memiliki method yang cocok), Go memungkinkan semuanya digunakan sebagai nilai Messenger. Inilah duck typing dalam praktik.

Coba sendiri

package main

import (
	"bufio"
	"fmt"
	"os"
)

func main() {
	scanner := bufio.NewScanner(os.Stdin)
	
	// Baca nomor telepon
	scanner.Scan()
	phoneNumber := scanner.Text()
	
	// Baca alamat email
	scanner.Scan()
	email := scanner.Text()
	
	// Baca nama merpati
	scanner.Scan()
	pigeonName := scanner.Text()
	
	// Baca pesan untuk disiarkan
	scanner.Scan()
	message := scanner.Text()
	
	// TODO: Buat satu dari setiap tipe pengirim pesan (Phone, Computer, Pigeon)
	
	// TODO: Kumpulkan semua pengirim pesan ke dalam slice bertipe Messenger
	
	// TODO: Gunakan Broadcast untuk mengirim pesan melalui semua pengirim pesan
	
	// TODO: Cetak setiap hasil pada baris tersendiri
	
	// Penampung sementara untuk menggunakan variabel (hapus saat kamu mengimplementasikannya)
	_ = phoneNumber
	_ = email
	_ = pigeonName
	_ = message
}
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