Generics ในทางปฏิบัติ: ข้อควรระวัง
เรียนรู้ว่าเมื่อใดควรใช้ generics และข้อผิดพลาดที่พบบ่อย
Generics ในทางปฏิบัติ: ข้อควรระวัง เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
การทำให้เป็นเจเนอริกมากเกินไป
ไม่ใช่ทุกฟังก์ชันที่จำเป็นต้องเป็นเจเนอริก หากมีการใช้ชนิดที่เป็นรูปธรรมเพียงชนิดเดียว เจเนอริกจะเพิ่มความซับซ้อนโดยไม่ก่อประโยชน์ ควรเลือกใช้ชนิดที่เป็นรูปธรรม และปรับเป็นเจเนอริกเมื่อเริ่มมีโค้ดซ้ำ
การยืนยันชนิดภายในเจเนอริก
คุณไม่สามารถยืนยันชนิดหรือสลับชนิดภายในฟังก์ชันเจเนอริกโดยใช้พารามิเตอร์ชนิดเองได้ — เจเนอริกไม่ใช่แม่แบบ ให้ใช้อินเทอร์เฟซหรือแพ็กเกจ reflect แทน
// WRONG:
func Foo[T any](v T) {
if x, ok := v.(int); ok { // compile error
}
}Comparable ไม่ได้หมายถึง Ordered
comparable รองรับเฉพาะ == หากต้องการใช้ < หรือ > คุณต้องใช้ cmp.Ordered หรือข้อจำกัดแบบกำหนดเอง ข้อผิดพลาดที่พบบ่อยคือการคิดว่า comparable รองรับการจัดลำดับด้วย
เมธอดไม่สามารถเพิ่มพารามิเตอร์ชนิดได้
เมธอดของชนิดเจเนอริกจะใช้พารามิเตอร์ของชนิดนั้นซ้ำ แต่ไม่สามารถเพิ่มพารามิเตอร์ชนิดใหม่ได้ หากเมธอดต้องใช้พารามิเตอร์ชนิดเพิ่มเติม ให้ใช้ฟังก์ชันระดับบนสุดแทน
// WRONG:
func (s *Stack[T]) MapTo[U any]() []U // compile errorค่า nil และค่าศูนย์
สำหรับพารามิเตอร์ชนิดตัวชี้ ค่าศูนย์คือ nil ส่วนชนิดค่า ค่าศูนย์คือค่าศูนย์ของชนิดนั้น ควรจัดการกรณีค่าศูนย์เสมอ แทนที่จะสมมติว่าค่านั้นไม่ใช่ nil
ชุดเมธอดของอินเทอร์เฟซและเจเนอริก
ฟังก์ชันเจเนอริกที่มีข้อจำกัดเป็นอินเทอร์เฟซจะเรียกได้เฉพาะเมธอดที่ประกาศไว้ในอินเทอร์เฟซนั้น การเพิ่มเมธอดให้ชนิดที่เป็นรูปธรรมไม่ได้ทำให้เรียกเมธอดเหล่านั้นผ่านข้อจำกัดได้
โค้ดเพิ่มขึ้นจากการสร้างอินสแตนซ์ (รูปร่าง GC)
Go แชร์การทำงานสำหรับชนิดที่มีรูปร่าง GC เหมือนกัน (เช่น ชนิดตัวชี้ทั้งหมดแชร์การทำงานเดียวกัน) ส่วนชนิดพื้นฐานแต่ละชนิดจะมีการทำงานของตนเอง แต่แนวทางของ Go ยังคงรักษาขนาดไบนารีให้อยู่ในระดับเหมาะสม
Any ไม่ใช่ interface{}
any เป็นนามแฝงของ interface{} แต่ฟังก์ชันเจเนอริก F[T any] ไม่เหมือนกับ F(v interface{}) — ในฟังก์ชันเจเนอริก T คือชนิดที่เป็นรูปธรรม ณ จุดเรียกใช้ จึงยังคงข้อมูลชนิดไว้
ชนิดเจเนอริกแบบเรียกซ้ำ
Go ไม่รองรับการนิยามพารามิเตอร์ชนิดแบบเรียกซ้ำ เช่น type Tree[T Tree[T]] ให้ใช้การประกอบแทน:
type TreeNode[T any] struct {
Val T
Left *TreeNode[T]
Right *TreeNode[T]
}ตัวช่วยที่สร้างอินสแตนซ์ไว้ล่วงหน้า
สำหรับโค้ดที่ไวต่อประสิทธิภาพ ให้สร้างอินสแตนซ์ของฟังก์ชันเจเนอริกที่ใช้บ่อยไว้ล่วงหน้าเป็นฟังก์ชันระดับบนสุด เพื่อหลีกเลี่ยงค่าใช้จ่ายจากการอนุมานชนิดซ้ำ ๆ (แม้ว่าคอมไพเลอร์ Go จะจัดการเรื่องนี้ได้ดี)
การทดสอบโค้ดเจเนอริก
ทดสอบฟังก์ชันเจเนอริกด้วยการสร้างอินสแตนซ์หลายแบบ: อย่างละหนึ่งแบบสำหรับข้อจำกัดที่แตกต่างกัน (int, string และชนิดกำหนดเอง) วิธีนี้ช่วยตรวจจับกรณีขอบที่ขึ้นอยู่กับข้อจำกัด
func TestMap(t *testing.T) {
got := Map([]int{1,2}, double)
// test with strings too
gotS := Map([]string{"a","b"}, strings.ToUpper)
}ตรวจสอบอย่างรวดเร็ว
เหตุใดคุณจึงไม่สามารถสลับชนิดด้วยพารามิเตอร์ชนิดเจเนอริก T ภายในฟังก์ชันเจเนอริกได้
สรุป: ข้อผิดพลาดในการใช้เจเนอริก
ประเด็นสำคัญ:
- อย่าทำให้เป็นเจเนอริกมากเกินไป ชนิดที่เป็นรูปธรรมจะง่ายกว่าเมื่อมีการใช้เพียงครั้งเดียว
- ไม่มีการสลับชนิดหรือยืนยันชนิดของ T ภายในฟังก์ชันเจเนอริก
- comparable ไม่ได้หมายถึง ordered ให้ใช้ cmp.Ordered เพื่อรองรับ <
- เมธอดไม่สามารถเพิ่มพารามิเตอร์ชนิดใหม่ได้
คำถามที่พบบ่อย
บทเรียน “Generics ในทางปฏิบัติ: ข้อควรระวัง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “Generics ในทางปฏิบัติ: ข้อควรระวัง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “Generics ในทางปฏิบัติ: ข้อควรระวัง”
เรียนรู้ว่าเมื่อใดควรใช้ generics และข้อผิดพลาดที่พบบ่อย คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “Generics ในทางปฏิบัติ: ข้อควรระวัง” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ไวยากรณ์พารามิเตอร์ชนิดข้อมูล
- ข้อจำกัด: comparable และ interface
- โครงสร้างข้อมูลทั่วไป
- Generics ในทางปฏิบัติ: ข้อควรระวัง