0Pricing
Go Academy · บทเรียน

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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ไวยากรณ์พารามิเตอร์ชนิดข้อมูล
  2. ข้อจำกัด: comparable และ interface
  3. โครงสร้างข้อมูลทั่วไป
  4. Generics ในทางปฏิบัติ: ข้อควรระวัง
← กลับไปที่ Go Academy