Các phần trước:
Phần 1: Packages, variables và functions.
Phần 2: Điều khiển luồng với if, else, switch và defer.
Methods
Trong Go không có class, chúng ta có thể dùng struct thay cho class như ở phần trước. Tuy nhiên trong struct mới chỉ có thuộc tính chứ chưa có phương thức. Để ứng dụng được phương thức (method) như các ngôn ngữ hướng đối tượng khác ta sẽ cần khai báo function kèm theo một tham số đặc biệt gọi là receiver argument. Receiver argument nằm ở giữa từ khóa func và tên của function, nó sẽ chỉ ra một type (thường là một struct) để áp dụng hàm này làm phương thức. Ví dụ:
package main
import (
"fmt"
"math"
)
// Định nghĩa struct Vertex với 2 thuộc tính X và Y
type Vertex struct {
X, Y float64
}
// Tạo phương thức Abs() cho struct Vertex (receiver argument)
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
func main() {
// Khởi tạo struct
v := Vertex{3, 4}
// Gọi phương thức Abs() của struct
fmt.Println(v.Abs())
}
Interfaces
package main
import "fmt"
// Định nghĩa interface I với 1 method là M()
type I interface {
M()
}
// Định nghĩa struct T với 1 field là S kiểu string
type T struct {
S string
}
// Định nghĩa phương thức M() cho struct T
// Struct T sẽ tự động implement interface I
func (t T) M() {
fmt.Println(t.S)
}
func main() {
// Khởi tạo biến i có kiểu là interface I
var i I = T{"hello"}
// Gọi phương thức M()
i.M()
}
- Type đã triển khai interface buộc phải có đầy đủ các method được định nghĩa trong interface. Ví dụ:
package main
import "fmt"
// Định nghĩa interface I với 1 method là M() và N()
type I interface {
M(),
N()
}
// Định nghĩa struct T
type T struct {
S string
}
// Định nghĩa phương thức M() cho struct T
// Struct T sẽ tự động implement interface I
func (t T) M() {
fmt.Println(t.S)
}
func main() {
// Khởi tạo biến i có kiểu là interface I
var i I = T{"hello"}
// Gọi phương thức M()
i.M()
// Kết quả sẽ báo lỗi vì struct T implement interface I,
// nhưng không có đủ các method đã khai báo (thiếu method N())
}
- Một interface mà không có chứa method nào thì gọi là interface rỗng (Emtpy Interface). Interface rỗng có thể lưu mọi loại dữ liệu nên thường được dùng trong trường hợp các hàm xử lý mà cần tham số động (không biết trước kiểu dữ liệu). Ví dụ:
package main
import "fmt"
func main() {
var i interface{} // i là một empty interface
// Họi hàm describe với tham số truyền vào là một số
i = 42
describe(i)
// Họi hàm describe với tham số truyền vào là một chuỗi
i = "hello"
describe(i)
}
// Hàm describe có tham số truyền vào là một empty interface
// do đó khi thực thi ta có thể truyền vào kiểu dữ liệu nào cũng được
func describe(i interface{}) {
fmt.Printf("(%v, %T)\n", i, i)
}
Bình luận