Receiver con trỏ
Thuộc phần Logic và luồng điều khiển trong hành trình GO của Coddy. Bài học 8 trên 68.
Receiver giá trị hoạt động với bản sao của struct, còn receiver con trỏ hoạt động trực tiếp với instance struct ban đầu. Khi định nghĩa một phương thức với receiver con trỏ, phương thức có thể sửa đổi dữ liệu ban đầu vì nó nhận một con trỏ đến struct thay vì một bản sao.
Để tạo một receiver con trỏ, bạn thêm dấu hoa thị * trước tên kiểu trong phần khai báo receiver:
type Person struct {
Name string
Age int
}
func (p *Person) haveBirthday() {
p.Age++ // Thao tác này thay đổi struct gốc
}Trong ví dụ này, (p *Person) là receiver con trỏ. Khi bạn gọi phương thức haveBirthday trên một instance Person, phương thức nhận một con trỏ đến struct ban đầu. Mọi thay đổi đối với các trường của struct thông qua con trỏ này sẽ sửa đổi dữ liệu ban đầu vĩnh viễn.
Receiver con trỏ rất cần thiết khi các phương thức của bạn cần cập nhật những trường của struct, nên chúng rất phù hợp với các thao tác làm thay đổi trạng thái dữ liệu.
Thử thách
DễTrong thử thách này, bạn sẽ luyện tập tạo phương thức với bộ nhận con trỏ bằng cách xây dựng một hệ thống tài khoản ngân hàng đơn giản. Bạn sẽ tạo một struct Account và định nghĩa các phương thức có thể thay đổi số dư tài khoản bằng bộ nhận con trỏ.
Bạn sẽ nhận được ba đầu vào:
- Một chuỗi biểu thị tên chủ tài khoản (ví dụ:
"John Smith") - Một chuỗi biểu thị số dư ban đầu của tài khoản (ví dụ:
"1000.50") - Một chuỗi biểu thị số tiền giao dịch (ví dụ:
"250.75")
Nhiệm vụ của bạn là:
- Định nghĩa một struct
Accountcó hai trường:Name(chuỗi) vàBalance(float64) - Tạo một phương thức có tên
depositvới bộ nhận con trỏ, cộng số tiền đã cho vào số dư tài khoản - Tạo một phương thức có tên
withdrawvới bộ nhận con trỏ, trừ số tiền đã cho khỏi số dư tài khoản - Tạo một phương thức có tên
displayBalancevới bộ nhận giá trị, in thông tin tài khoản theo định dạng:"Account: [name], Balance: $[balance]" - Phân tích cú pháp các đầu vào để tạo một instance
Account - Gọi
displayBalanceđể hiển thị số dư ban đầu - Gọi
depositvới số tiền giao dịch - Gọi
displayBalanceđể hiển thị số dư sau khi nạp tiền - Gọi
withdrawvới số tiền giao dịch - Gọi
displayBalanceđể hiển thị số dư cuối cùng
Số dư cần được hiển thị với độ chính xác đến hai chữ số thập phân. Thử thách này minh họa cách bộ nhận con trỏ cho phép phương thức thay đổi dữ liệu của struct gốc, khác với bộ nhận giá trị, vốn hoạt động trên các bản sao.
Tự làm thử
package main
import (
"fmt"
"strconv"
)
// TODO: Định nghĩa struct Account tại đây
// TODO: Định nghĩa phương thức (method) deposit với receiver dạng con trỏ tại đây
// TODO: Định nghĩa phương thức withdraw với receiver dạng con trỏ tại đây
// TODO: Định nghĩa phương thức displayBalance với receiver dạng giá trị tại đây
func main() {
// Đọc đầu vào
var name string
var initialBalanceStr string
var transactionAmountStr string
fmt.Scanln(&name)
fmt.Scanln(&initialBalanceStr)
fmt.Scanln(&transactionAmountStr)
// Chuyển các chuỗi đầu vào sang kiểu dữ liệu phù hợp
initialBalance, _ := strconv.ParseFloat(initialBalanceStr, 64)
transactionAmount, _ := strconv.ParseFloat(transactionAmountStr, 64)
// TODO: Tạo một instance của Account
// TODO: Hiển thị số dư ban đầu, nạp tiền, hiển thị số dư, rút tiền, hiển thị số dư cuối cùng
}Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Logic và luồng điều khiển
1Luồng điều khiển nâng cao
Switch với `fallthrough`Thoát khỏi vòng lặp lồng nhauTiếp tục một vòng lặp cụ thểCâu lệnh `goto`Ôn tập: điều khiển vòng lặp nâng cao4Dự án: Danh sách việc cần làm đơn giản
Thiết lập dự ánThêm một việc cần làm2Struct và phương thức
Định nghĩa phương thức cho structReceiver giá trịReceiver con trỏChọn receiverPhương thức và hàmÔn tập: hành vi của struct5Tìm hiểu chuyên sâu về map
Map chứa structCon trỏ làm giá trị của mapKiểm tra map nilSo sánh các mapÔn tập: bộ đếm tần suất từ8Dự án: Quản lý hàng tồn kho đơn giản
Tổng quan dự ánKiểm tra hàng tồn kho3Interface (cơ bản)
Interface là gì?Định nghĩa interfaceTriển khai interfaceDùng kiểu interfaceInterface rỗngKhẳng định kiểuType switchÔn tập: hình dạng và hành viTự luyện tập: Trình biên dịch Go online