Người nhận và Giao diện
Các phương thức có bộ nhận giá trị có thể được gọi bằng cả giá trị và con trỏ.
Các phương thức có bộ nhận con trỏ chỉ có thể được gọi bằng con trỏ hoặc các giá trị có thể địa chỉ.
Ví dụ,
type S struct {
data string
}
func (s S) Read() string {
return s.data
}
func (s *S) Write(str string) {
s.data = str
}
sVals := map[int]S{1: {"A"}}
// Chỉ có thể gọi Read bằng giá trị
sVals[1].Read()
// Đoạn mã này sẽ không được biên dịch:
// sVals[1].Write("test")
sPtrs := map[int]*S{1: {"A"}}
// Cả hai phương thức Read và Write có thể được gọi bằng con trỏ
sPtrs[1].Read()
sPtrs[1].Write("test")
Tương tự, ngay cả khi một phương thức có bộ nhận giá trị, nó vẫn có thể đáp ứng một giao diện bằng cách sử dụng bộ nhận con trỏ.
type F interface {
f()
}
type S1 struct{}
func (s S1) f() {}
type S2 struct{}
func (s *S2) f() {}
s1Val := S1{}
s1Ptr := &S1{}
s2Val := S2{}
s2Ptr := &S2{}
var i F
i = s1Val
i = s1Ptr
i = s2Ptr
// Đoạn mã sau sẽ không biên dịch được vì s2Val là giá trị và phương thức f của S2 không có bộ nhận giá trị
// i = s2Val
Effective Go chứa những giải thích tuyệt vời về con trỏ so với giá trị.
Ghi chú bổ sung:
- Một kiểu có thể có một bộ phương thức với bộ nhận giá trị và một bộ phương thức với bộ nhận con trỏ
- Bộ phương thức có bộ nhận giá trị là một phần con của bộ phương thức có bộ nhận con trỏ, nhưng không ngược lại
- Quy tắc
- Đối tượng giá trị chỉ có thể sử dụng bộ phương thức với bộ nhận giá trị
- Đối tượng con trỏ có thể sử dụng bộ phương thức với bộ nhận giá trị + bộ phương thức với bộ nhận con trỏ
- Khớp giao diện (hoặc triển khai)
- Kiểu khớp với giao diện nếu nó triển khai tất cả các phương thức của giao diện
- Cụ thể, đó là cả bộ phương thức giá trị của kiểu khớp với giao diện hoặc bộ phương thức con trỏ khớp với giao diện
Có hai loại khớp cụ thể:
- Bộ phương thức giá trị khớp với giao diện
- Hoàn toàn có thể gán một đối tượng giá trị hoặc con trỏ vào biến giao diện vì cả hai đều chứa bộ phương thức giá trị
- Bộ phương thức con trỏ khớp với giao diện
- Chỉ có thể gán một đối tượng con trỏ vào biến giao diện vì chỉ bộ phương thức con trỏ mới khớp với giao diện
- Nếu gán một đối tượng giá trị vào biến giao diện, điều này sẽ kích hoạt cơ chế kiểm tra sự sống của giao diện trong quá trình biên dịch
Về việc tại sao i = s2Val kích hoạt một lỗi, điều này là do bộ phương thức giá trị và giao diện không khớp nhau.