Methods & Interfaces
แนวคิด polymorphism ของ Go
หัวข้อที่มีชื่อว่า “แนวคิด polymorphism ของ Go”ภาษาเชิงวัตถุส่วนใหญ่ผูก polymorphism ไว้กับลำดับชั้นของ class: คุณต้องประกาศว่า type หนึ่ง implements interface ใด, ต้อง extends base class, และ compiler จะบังคับโครงสร้างสายเลือดนั้น Go ตัดทิ้งลำดับชั้นทั้งหมด
ใน Go named type ใดก็ตามสามารถมี method ได้ และ type ใดที่มี method ถูกต้องก็ตอบสนอง interface โดยอัตโนมัติ — ไม่ต้องประกาศ นี่คือ implicit interface satisfaction และเป็นการตัดสินใจออกแบบที่สำคัญที่สุดของภาษา
การผสม methods และ interfaces ให้คุณได้:
- Polymorphism โดยไม่มีต้นไม้ inheritance
- Dependency inversion โดยไม่ต้องพึ่ง framework — รับ interface, คืน struct
- Composition โดยไม่ต้องใช้
extends— embed types เพื่อยกระดับ fields และ methods
แผนที่โมดูล
หัวข้อที่มีชื่อว่า “แผนที่โมดูล”| บทเรียน | สิ่งที่คุณจะเรียนรู้ |
|---|---|
| Methods | ประกาศ methods บน named type ใดก็ได้; value vs pointer receiver; method sets |
| Interfaces | นิยามและตอบสนอง interface โดยนัย; small interfaces; empty interface any |
| Type Assertions | x.(T), comma-ok form, และ switch v := x.(type) |
| Embedding | Struct embedding, promoted fields/methods, interface embedding, composition แทน inheritance |
ตัวอย่างแรกที่รันได้
หัวข้อที่มีชื่อว่า “ตัวอย่างแรกที่รันได้”โค้ดด้านล่างนิยาม method บน struct, ประกาศ interface หนึ่ง method, และเรียก method ผ่าน interface — ทั้งหมดในไม่ถึง 20 บรรทัด
package main
import "fmt"
type Rectangle struct { Width, Height float64}
func (r Rectangle) Area() float64 { return r.Width * r.Height}
type Sizer interface { Area() float64}
func printArea(s Sizer) { fmt.Printf("area = %.2f\n", s.Area())}
func main() { r := Rectangle{Width: 4, Height: 3} fmt.Println(r.Area()) printArea(r)}Loading Go runtime (first run only, ~8 MB)…
ข้อแลกเปลี่ยน
หัวข้อที่มีชื่อว่า “ข้อแลกเปลี่ยน”| สิ่งที่ได้ | ประโยชน์ | ต้นทุน |
|---|---|---|
| implicit interface satisfaction | decoupled code, ไม่มี import dependency บน interface | ยากต่อการ discover ว่า type ใด implement interface ใด |
| value receiver | immutable, เรียกได้บน non-addressable values | copy struct ทุกครั้ง |
| pointer receiver | mutate ได้, ไม่ copy | ต้อง nil-check, ต้องการ addressable value |
| embedding (composition) | reuse methods/fields โดยไม่ inherit | ไม่มี virtual dispatch — ต้องใช้ interface สำหรับ polymorphism |
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”- interface คือ abstract class — ใน Go interface มีแค่ method signatures ไม่มี implementation, ไม่มี state
- embedding = inheritance — embedded type ไม่รู้จัก outer type ไม่มี override หรือ virtual dispatch
- nil interface เสมอ == nil — interface ที่เก็บ nil pointer ไม่ใช่ nil interface; (nil, nil) != (*T, nil)
💡 ตัวอย่างจากของจริง
Go standard library ใช้ io.Reader และ io.Writer เป็น interface หลัก — os.File, bytes.Buffer, net.Conn, http.Body ล้วน implement สิ่งเดียวกัน ทำให้ compose ได้ทั่ว ecosystem
Kubernetes ใช้ runtime.Object interface กับทุก Kubernetes resource — controller เขียนครั้งเดียวทำงานกับ Pod, Deployment, Service ได้ทุก type