สตรักต์ไม่ระบุชื่อและการประกอบ
การฝังและการนำโค้ดกลับมาใช้ใหม่ด้วยสตรักต์
สตรักต์ไม่ระบุชื่อและการประกอบ เป็นบทเรียน Go Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Go Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
สตรักต์ไม่มีชื่อ
สตรักต์ไม่มีชื่อคือสตรักต์ที่ไม่มีชนิดข้อมูลที่มีชื่อ กำหนดขึ้นโดยตรงในจุดที่ใช้งาน และมีประโยชน์สำหรับข้อมูลอายุสั้น การทดสอบแบบใช้ตาราง และการจัดกลุ่มเฉพาะครั้ง:
package main
import "fmt"
func main() {
point := struct{ X, Y int }{X: 3, Y: 7}
fmt.Println(point.X, point.Y)
}สตรักต์ไม่มีชื่อในการทดสอบแบบตาราง
แนวทางที่ใช้กันทั่วไปใน Go คือใช้สไลซ์ของสตรักต์ไม่มีชื่อสำหรับการทดสอบแบบใช้ตาราง:
package main
import "fmt"
func double(n int) int { return n * 2 }
func main() {
tests := []struct{ input, want int }{
{1, 2}, {5, 10}, {0, 0},
}
for _, tt := range tests {
got := double(tt.input)
if got != tt.want {
fmt.Printf("FAIL: double(%d) = %d, want %d\n", tt.input, got, tt.want)
}
}
fmt.Println("all tests passed")
}การฝังสตรักต์
การฝังชนิดข้อมูลไว้ภายในสตรักต์จะทำให้ฟิลด์และเมธอดของชนิดนั้นเข้าถึงได้จากสตรักต์ภายนอก:
package main
import "fmt"
type Animal struct{ Name string }
func (a Animal) Speak() string { return a.Name + " speaks" }
type Dog struct {
Animal // embedded
Breed string
}
func main() {
d := Dog{Animal: Animal{"Rex"}, Breed: "Labrador"}
fmt.Println(d.Name) // promoted field
fmt.Println(d.Speak()) // promoted method
}การฝังหลายชนิดข้อมูล
สตรักต์สามารถฝังชนิดข้อมูลได้หลายชนิด หากเกิดความขัดแย้ง เช่น มีชื่อฟิลด์หรือเมธอดเดียวกัน ต้องแก้ไขโดยระบุให้ชัดเจน:
package main
import "fmt"
type Logger struct{}
func (Logger) Log(s string) { fmt.Println("[LOG]", s) }
type Metrics struct{}
func (Metrics) Count() int { return 42 }
type Service struct {
Logger
Metrics
Name string
}
func main() {
svc := Service{Name: "auth"}
svc.Log("started") // from Logger
fmt.Println(svc.Count()) // from Metrics
}การฝังเทียบกับการสืบทอด
Go ไม่มีการสืบทอดคลาส การฝังคือการประกอบ:
- การฝังทำให้เข้าถึงฟิลด์และเมธอดได้จากชนิดข้อมูลภายนอก แต่ชนิดข้อมูลภายนอกไม่ใช่ชนิดย่อย
- คุณไม่สามารถส่ง
Dogแทนที่Animalที่ต้องการได้ - ใช้อินเทอร์เฟซสำหรับพหุสัณฐาน และใช้การฝังเพื่อใช้โค้ดซ้ำ
การเขียนทับเมธอดที่เข้าถึงได้จากการฝัง
สตรักต์ภายนอกสามารถบังเมธอดที่ฝังอยู่ได้ด้วยการกำหนดเมธอดของตนเอง:
package main
import "fmt"
type Base struct{}
func (Base) Hello() string { return "Base hello" }
type Child struct{ Base }
func (Child) Hello() string { return "Child hello" } // shadows Base.Hello
func main() {
c := Child{}
fmt.Println(c.Hello()) // Child hello
fmt.Println(c.Base.Hello()) // Base hello (explicit)
}สตรักต์ไม่มีชื่อสำหรับการกำหนดค่า
ใช้สตรักต์ไม่มีชื่อเพื่อจัดกลุ่มการกำหนดค่าที่เกี่ยวข้องกันโดยไม่ต้องกำหนดชนิดข้อมูลที่มีชื่อ:
package main
import "fmt"
func main() {
cfg := struct {
Host string
Port int
TLS bool
}{
Host: "api.example.com",
Port: 443,
TLS: true,
}
fmt.Println(cfg)
}การฝังอินเทอร์เฟซ
การฝังอินเทอร์เฟซในสตรักต์มีประโยชน์สำหรับการจำลองและการใช้งานเริ่มต้น:
package main
import "fmt"
type Reader interface{ Read() string }
type Mock struct{ Reader } // embed interface
func main() {
m := Mock{}
fmt.Printf("%T\n", m.Reader) // <nil> — not set
// Assign a real impl at test time:
_ = m
}ข้อควรระวังในการประกอบสตรักต์
ควรระวังเรื่องต่อไปนี้:
- ตัวเลือกกำกวมเมื่อชนิดข้อมูลที่ฝังสองชนิดมีชื่อฟิลด์หรือเมธอดเดียวกัน
- พอยน์เตอร์ที่ฝังเป็น nil ซึ่งทำให้เกิดข้อผิดพลาดรุนแรงเมื่อเรียกเมธอดของพอยน์เตอร์นั้น
- อย่าลืมว่าการฝังไม่ใช่การสืบทอด คุณไม่สามารถใช้ชนิดข้อมูลภายนอกแทนชนิดข้อมูลที่ฝังอยู่ได้
การเปรียบเทียบสตรักต์ไม่มีชื่อ
สตรักต์ไม่มีชื่อสองรายการที่มีชื่อและชนิดของฟิลด์เหมือนกัน สามารถกำหนดค่าให้แก่กันได้ หากแท็กของสตรักต์ตรงกันด้วย:
package main
import "fmt"
func main() {
a := struct{ X, Y int }{1, 2}
b := struct{ X, Y int }{1, 2}
fmt.Println(a == b) // true
}ตรวจสอบความเข้าใจอย่างรวดเร็ว
การฝังชนิดข้อมูลในสตรักต์ช่วยให้เกิดอะไร
สรุป: การประกอบ
ประเด็นสำคัญ:
- สตรักต์ไม่มีชื่อเหมาะสำหรับการทดสอบแบบตารางและข้อมูลอายุสั้น
- การฝังทำให้เข้าถึงฟิลด์และเมธอดได้จากชนิดข้อมูลภายนอก เป็นการประกอบ ไม่ใช่การสืบทอด
- ชนิดข้อมูลภายนอกสามารถบังเมธอดที่ฝังอยู่ได้
- แก้ไขตัวเลือกกำกวมโดยระบุให้ชัดเจน
- ใช้อินเทอร์เฟซสำหรับพหุสัณฐาน
โจทย์ฝึกปฏิบัติ
สร้างสตรักต์ TimestampedRecord ที่ฝัง Timestamp struct{ CreatedAt, UpdatedAt string } และ Data struct{ Key, Value string } สร้างอินสแตนซ์แล้วพิมพ์ฟิลด์ที่เข้าถึงได้จากสตรักต์ภายนอกทั้งหมด
คำถามที่พบบ่อย
บทเรียน “สตรักต์ไม่ระบุชื่อและการประกอบ” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “สตรักต์ไม่ระบุชื่อและการประกอบ” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Go Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Go Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “สตรักต์ไม่ระบุชื่อและการประกอบ”
การฝังและการนำโค้ดกลับมาใช้ใหม่ด้วยสตรักต์ คุณปฏิบัติ Go Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Go Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Go Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “สตรักต์ไม่ระบุชื่อและการประกอบ” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Go Academy นี้ได้ไหม
ได้ บทเรียน Go Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การกำหนดและใช้งานสตรักต์
- เมธอดบนสตรักต์
- รูปแบบคอนสตรักเตอร์
- สตรักต์ไม่ระบุชื่อและการประกอบ