Con trỏ hữu ích vì một số lý do. Con trỏ cho phép kiểm soát việc bố trí bộ nhớ (ảnh hưởng đến hiệu quả của bộ đệm CPU). Trong Go, chúng ta có thể xác định một cấu trúc mà tất cả các thành viên nằm trong bộ nhớ liền kề:
type Point struct {
x, y int
}
type LineSegment struct {
source, destination Point
}
Trong trường hợp này, các Point
cấu trúc được nhúng trong LineSegment
cấu trúc. Nhưng không phải lúc nào bạn cũng có thể nhúng dữ liệu trực tiếp. Nếu bạn muốn hỗ trợ các cấu trúc như cây nhị phân hoặc danh sách liên kết, thì bạn cần hỗ trợ một số loại con trỏ.
type TreeNode {
value int
left *TreeNode
right *TreeNode
}
Java, Python, v.v. không gặp vấn đề này vì nó không cho phép bạn nhúng các kiểu kết hợp, vì vậy không cần phải phân biệt cú pháp giữa nhúng và trỏ.
Các vấn đề với cấu trúc Swift / C # được giải quyết bằng con trỏ Go
Một lựa chọn tốt để thực hiện điều này cũng để phân biệt giữa struct
và class
như C # và Swift không. Nhưng điều này có những hạn chế. Mặc dù bạn thường có thể chỉ định rằng một hàm nhận cấu trúc làm inout
tham số để tránh sao chép cấu trúc, nhưng nó không cho phép bạn lưu trữ các tham chiếu (con trỏ) đến cấu trúc. Điều này có nghĩa là bạn không bao giờ có thể coi một cấu trúc là một kiểu tham chiếu khi bạn thấy rằng hữu ích, ví dụ: để tạo một bộ phân bổ nhóm (xem bên dưới).
Bộ phân bổ bộ nhớ tùy chỉnh
Sử dụng con trỏ, bạn cũng có thể tạo bộ phân bổ nhóm của riêng mình (điều này rất đơn giản với nhiều kiểm tra được loại bỏ để chỉ hiển thị nguyên tắc):
type TreeNode {
value int
left *TreeNode
right *TreeNode
nextFreeNode *TreeNode; // For memory allocation
}
var pool [1024]TreeNode
var firstFreeNode *TreeNode = &pool[0]
func poolAlloc() *TreeNode {
node := firstFreeNode
firstFreeNode = firstFreeNode.nextFreeNode
return node
}
func freeNode(node *TreeNode) {
node.nextFreeNode = firstFreeNode
firstFreeNode = node
}
Hoán đổi hai giá trị
Con trỏ cũng cho phép bạn thực hiện swap
. Đó là hoán đổi giá trị của hai biến:
func swap(a *int, b *int) {
temp := *a
*a = *b
*b = temp
}
Phần kết luận
Java chưa bao giờ có thể thay thế hoàn toàn C ++ cho lập trình hệ thống tại những nơi như Google, một phần vì hiệu suất không thể được điều chỉnh đến cùng mức mở rộng do thiếu khả năng kiểm soát việc bố trí và sử dụng bộ nhớ (bộ nhớ cache ảnh hưởng đáng kể đến hiệu suất). Go đã nhằm mục đích thay thế C ++ trong nhiều lĩnh vực và do đó cần hỗ trợ con trỏ.