Lesson 15 — Struct & Method

Ba module tương tác: (1) Memory layout — drag reorder field thấy padding co lại, (2) Receiver picker — slider để chọn value/pointer receiver, (3) Embedding visualizer — animate gọi method qua promotion + toggle override.

1. Memory layout — thứ tự field ảnh hưởng size

Chọn 1 preset, hoặc drag field để đổi thứ tự. Memory strip phía dưới cập nhật real-time, ô padding tự thêm để giữ alignment.

bool (1B) int32 (4B) int64 (8B) string (16B) padding
Memory layout (mỗi cell = 1 byte):
Size hiện tại: ? byte
Tối ưu (lớn→nhỏ): ? byte
Padding lãng phí: ? byte
Vì sao có padding?

CPU 64-bit đọc RAM nhanh nhất khi address chia hết cho 8 (alignment 8 byte cho int64). Compiler chèn padding để mỗi field có offset đúng alignment. Sắp lớn→nhỏ giảm "kẽ hở".

Tổng size cuối cùng cũng phải chia hết cho alignment lớn nhất của struct (tail padding).

2. Receiver picker — value hay pointer?

Slider chọn kích thước struct (byte) và checkbox "method có mutate không?". Hệ thống suggest receiver phù hợp + giải thích trade-off.

→ Value receiver

Struct nhỏ, không mutate — value receiver OK.

func (s Struct) Method() { ... }

3. Embedding — promotion & override

SVG dưới hiển thị Manager embed Employee. Bấm Gọi m.Greet() để xem Go chọn method nào — qua promotion hay qua override.

type Manager struct { Employee { // embedded Name string // "Alice" Salary float64 // 50000 method Greet() (value receiver) } Reports int // 5 }
Bấm nút để bắt đầu trace...
Vì sao embedding ≠ inheritance?

Embedding là "has-a" — Manager chứa Employee. Inheritance (Java/C++) là "is-a" — Manager Employee. Trong Go, Manager KHÔNG dùng được như Employee (không assign sang biến Employee được). Polymorphism phải qua interface (L18).

Khi gọi m.Greet(): nếu Manager có method Greet() riêng → gọi method đó (shadow). Nếu không → gọi method của Employee qua promotion.

Tham khảo nhanh — receiver cheat sheet

Tình huống Receiver
Cần mutate struct*T (pointer)
Struct > 64 byte (cache line)*T
Struct chứa sync.Mutex*T (Mutex không nên copy)
Type đã có 1 method *T → các method khác*T (nhất quán)
Struct nhỏ (Point, time.Time), không mutateT (value)
Method read-only và type chưa có pointer method nàoT