การกำหนดและใช้งาน interface
การทำให้สอดคล้องโดยปริยายและ interface ว่าง
การกำหนดและใช้งาน interface เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
อินเทอร์เฟซคืออะไร
อินเทอร์เฟซใน Go คือชุดลายเซ็นของเมธอด ชนิดข้อมูลใดก็ตามที่มีเมธอดเหล่านั้นครบจะรองรับอินเทอร์เฟซโดยอัตโนมัติ — ไม่จำเป็นต้องใช้คีย์เวิร์ด implements แนวคิดนี้เรียกว่าการกำหนดชนิดข้อมูลตามโครงสร้างหรือการกำหนดชนิดแบบเป็ด
การประกาศอินเทอร์เฟซ
กำหนดอินเทอร์เฟซด้วยคีย์เวิร์ด type:
package main
import "fmt"
type Shape interface {
Area() float64
Perimeter() float64
}
type Circle struct{ Radius float64 }
func (c Circle) Area() float64 { return 3.14159 * c.Radius * c.Radius }
func (c Circle) Perimeter() float64 { return 2 * 3.14159 * c.Radius }
func main() {
var s Shape = Circle{5}
fmt.Printf("Area: %.2f\n", s.Area())
}การรองรับโดยอัตโนมัติ
ไม่จำเป็นต้องประกาศเจตนา หากชนิดข้อมูลมีเมธอดที่ถูกต้อง ก็จะรองรับอินเทอร์เฟซโดยอัตโนมัติ:
package main
import "fmt"
type Greeter interface{ Greet() string }
type English struct{}
func (e English) Greet() string { return "Hello" }
type Spanish struct{}
func (s Spanish) Greet() string { return "Hola" }
func say(g Greeter) { fmt.Println(g.Greet()) }
func main() {
say(English{})
say(Spanish{})
}อินเทอร์เฟซว่าง
interface{} (หรือ any ใน Go 1.18 ขึ้นไป) ได้รับการรองรับจากชนิดข้อมูลทุกชนิด ใช้เมื่อไม่ทราบชนิดข้อมูลขณะคอมไพล์:
package main
import "fmt"
func printAny(v any) { fmt.Printf("%T: %v\n", v, v) }
func main() {
printAny(42)
printAny("hello")
printAny([]int{1,2,3})
}ค่าอินเทอร์เฟซ
ค่าอินเทอร์เฟซประกอบด้วยสองสิ่ง ได้แก่ ชนิดข้อมูลรูปธรรมและค่ารูปธรรม อินเทอร์เฟซ nil จะมีทั้งสองส่วนเป็น nil:
package main
import "fmt"
type Animal interface{ Sound() string }
type Dog struct{}
func (d Dog) Sound() string { return "woof" }
func main() {
var a Animal
fmt.Println(a == nil) // true
a = Dog{}
fmt.Println(a == nil) // false
fmt.Println(a.Sound())
}การรองรับอินเทอร์เฟซหลายรายการ
ชนิดข้อมูลหนึ่งสามารถรองรับอินเทอร์เฟซหลายรายการพร้อมกันได้:
package main
import "fmt"
type Reader interface{ Read() string }
type Writer interface{ Write(string) }
type ReadWriter interface{ Reader; Writer }
type File struct{ content string }
func (f *File) Read() string { return f.content }
func (f *File) Write(s string) { f.content = s }
func main() {
var rw ReadWriter = &File{}
rw.Write("hello")
fmt.Println(rw.Read())
}การกำหนดค่าให้อินเทอร์เฟซ
อินเทอร์เฟซที่กว้างกว่าสามารถเก็บค่ารูปธรรมที่แคบกว่าได้ การกำหนดค่าระหว่างชนิดอินเทอร์เฟซจำเป็นต้องให้ชนิดรูปธรรมรองรับอินเทอร์เฟซทั้งสอง:
package main
import "fmt"
type Stringer interface{ String() string }
type Point struct{ X, Y int }
func (p Point) String() string { return fmt.Sprintf("(%d,%d)", p.X, p.Y) }
func main() {
var s Stringer = Point{3, 4}
fmt.Println(s.String())
}กับดักอินเทอร์เฟซ nil
อินเทอร์เฟซที่ไม่เป็น nil แต่เก็บค่ารูปธรรมที่เป็น nil จะไม่เท่ากับ nil:
package main
import "fmt"
type MyErr struct{}
func (e *MyErr) Error() string { return "oops" }
func bad() error {
var e *MyErr // nil pointer
return e // returns non-nil interface!
}
func main() {
err := bad()
fmt.Println(err == nil) // false — common gotcha
}อินเทอร์เฟซช่วยให้ทดสอบได้
การกำหนดส่วนพึ่งพาเป็นอินเทอร์เฟซทำให้สามารถสลับการทำงานจริงเป็นการทำงานจำลองในชุดทดสอบได้:
package main
import "fmt"
type EmailSender interface{ Send(to, body string) error }
type MockSender struct{ Sent []string }
func (m *MockSender) Send(to, body string) error {
m.Sent = append(m.Sent, to)
return nil
}
func notify(s EmailSender, addr string) { s.Send(addr, "hello") }
func main() {
mock := &MockSender{}
notify(mock, "a@b.com")
fmt.Println(mock.Sent) // [a@b.com]
}รับอินเทอร์เฟซ คืนค่าโครงสร้าง
แนวทางปฏิบัติที่ดีของ Go คือ พารามิเตอร์ฟังก์ชันควรเป็นอินเทอร์เฟซเพื่อความยืดหยุ่น ส่วนชนิดค่าที่คืนควรเป็นชนิดรูปธรรม เพื่อให้ผู้เรียกทราบว่าจะได้รับอะไร:
package main
type Logger interface{ Log(string) }
type FileLogger struct{}
func (f *FileLogger) Log(s string) {}
func NewFileLogger() *FileLogger { // returns concrete
return &FileLogger{}
}
func process(l Logger) {} // accepts interface
func main() { process(NewFileLogger()) }ทำให้อินเทอร์เฟซมีขนาดเล็ก
ไลบรารีมาตรฐานของ Go นิยมใช้อินเทอร์เฟซขนาดเล็กมาก: io.Reader มีเมธอดเดียว และ io.Writer ก็มีเมธอดเดียว อินเทอร์เฟซขนาดเล็กนำไปประกอบใช้ได้ง่ายกว่าและสร้างการทำงานจำลองได้ง่ายกว่า
ตรวจสอบอย่างรวดเร็ว
ชนิดข้อมูลจำเป็นต้องประกาศหรือไม่ว่ารองรับอินเทอร์เฟซ
สรุปทบทวน: อินเทอร์เฟซ
ประเด็นสำคัญ:
- อินเทอร์เฟซกำหนดพฤติกรรม ไม่ใช่ข้อมูล
- การรองรับเกิดขึ้นโดยอัตโนมัติ — ไม่ต้องใช้คีย์เวิร์ด
implements - อินเทอร์เฟซว่าง (
any) รองรับชนิดข้อมูลทุกชนิด - ระวังกับดักอินเทอร์เฟซ nil
- ทำให้อินเทอร์เฟซมีขนาดเล็กและมุ่งเน้นเฉพาะงาน
โจทย์ฝึกปฏิบัติ
กำหนดอินเทอร์เฟซ Storage ที่มี Save(key, value string) error และ Load(key string) (string, error) จากนั้นสร้างการทำงานด้วย MemStorage ที่ใช้แมปเป็นโครงสร้างข้อมูลเบื้องหลังและทดสอบการทำงาน
คำถามที่พบบ่อย
บทเรียน “การกำหนดและใช้งาน interface” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การกำหนดและใช้งาน interface” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การกำหนดและใช้งาน interface”
การทำให้สอดคล้องโดยปริยายและ interface ว่าง คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “การกำหนดและใช้งาน interface” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกำหนดและใช้งาน interface
- interface ของไลบรารีมาตรฐานหลัก
- การยืนยันชนิดข้อมูลและสวิตช์ชนิดข้อมูล
- การประกอบ interface และแนวทางปฏิบัติที่ดี