ข้ามไปยังเนื้อหา

Methods & Interfaces

ภาษาเชิงวัตถุส่วนใหญ่ผูก 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 Assertionsx.(T), comma-ok form, และ switch v := x.(type)
EmbeddingStruct 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)
}
สิ่งที่ได้ประโยชน์ต้นทุน
implicit interface satisfactiondecoupled code, ไม่มี import dependency บน interfaceยากต่อการ discover ว่า type ใด implement interface ใด
value receiverimmutable, เรียกได้บน non-addressable valuescopy struct ทุกครั้ง
pointer receivermutate ได้, ไม่ 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

type ใน Go ประกาศว่าตอบสนอง interface อย่างไร?
อะไรที่สามารถมี methods ใน Go ได้?
อะไรคือทางเลือกของ Go แทน class inheritance?