Hướng dẫn cơ bản về cấu trúc trong Go

Xin chào các bạn đang học lập trình! Hôm nay, chúng ta sẽ bắt đầu một hành trình thú vị vào thế giới của các cấu trúc trong Go. Đừng lo lắng nếu bạn chưa bao giờ viết mã trước đây - tôi sẽ là người bạn thân thiện của bạn, và chúng ta sẽ cùng khám phá chủ đề này từng bước một. Vậy, hãy lấy một tách cà phê (hoặc trà, nếu đó là sở thích của bạn), và chúng ta cùng bắt đầu nhé!

Go - Structures

Cấu trúc là gì trong Go?

Trước khi bắt đầu, hãy hiểu cấu trúc là gì. Hãy tưởng tượng bạn đang tạo một sổ địa chỉ kỹ thuật số. Cho mỗi liên hệ, bạn cần lưu trữ nhiều thông tin khác nhau như tên, số điện thoại và địa chỉ email. Một cấu trúc trong Go cho phép bạn nhóm các dữ liệu liên quan này lại dưới một tên duy nhất. Nó giống như tạo một kiểu dữ liệu tùy chỉnh phù hợp với nhu cầu cụ thể của bạn.

Bây giờ, hãy cùng làm quen với một chút mã!

Định nghĩa một cấu trúc

Để định nghĩa một cấu trúc trong Go, chúng ta sử dụng từ khóa type tiếp theo là tên của cấu trúc và từ khóa struct. Dưới đây là cách chúng ta có thể định nghĩa một cấu trúc cho sổ địa chỉ kỹ thuật số của chúng ta:

type Contact struct {
Name        string
PhoneNumber string
Email       string
}

Trong ví dụ này, chúng ta đã tạo một cấu trúc叫做 Contact với ba trường: Name, PhoneNumber, và Email, đều có kiểu string.

Hãy phân tích điều này:

  • type cho Go biết chúng ta đang định nghĩa một kiểu mới
  • Contact là tên chúng ta đặt cho cấu trúc của mình
  • struct cho biết kiểu này là một cấu trúc
  • Trong dấu ngoặccurly, chúng ta liệt kê các trường của mình, mỗi trường có kiểu riêng

Truy cập các thành viên của cấu trúc

Bây giờ chúng ta đã định nghĩa cấu trúc của mình, hãy tạo một thể hiện của nó và truy cập các thành viên của nó:

func main() {
myFriend := Contact{
Name:        "Alice",
PhoneNumber: "123-456-7890",
Email:       "[email protected]",
}

fmt.Println("Name:", myFriend.Name)
fmt.Println("Phone:", myFriend.PhoneNumber)
fmt.Println("Email:", myFriend.Email)
}

Dưới đây là những gì đang xảy ra:

  1. Chúng ta tạo một Contact mới gọi là myFriend
  2. Chúng ta khởi tạo các trường của nó với các giá trị cụ thể
  3. Chúng ta truy cập và in mỗi trường bằng cách sử dụng ký tự gạch chéo (myFriend.Name, v.v.)

Khi bạn chạy đoạn mã này, bạn sẽ thấy thông tin liên hệ của Alice được in ra. Thật tuyệt vời phải không?

Cấu trúc làm đối số hàm

Cấu trúc trở nên mạnh mẽ hơn khi chúng ta sử dụng chúng với các hàm. Hãy tạo một hàm in thông tin liên hệ:

func printContact(c Contact) {
fmt.Printf("Name: %s\nPhone: %s\nEmail: %s\n", c.Name, c.PhoneNumber, c.Email)
}

func main() {
myFriend := Contact{
Name:        "Bob",
PhoneNumber: "098-765-4321",
Email:       "[email protected]",
}

printContact(myFriend)
}

Trong ví dụ này:

  • Chúng ta định nghĩa một hàm printContact nhận một Contact làm đối số
  • Trong main(), chúng ta tạo một Contact mới cho Bob
  • Chúng ta truyền myFriend vào printContact, sau đó in thông tin của Bob

Cách tiếp cận này cho phép chúng ta tái sử dụng mã và làm việc với dữ liệu của mình một cách hiệu quả hơn.

Con trỏ đến cấu trúc

Bây giờ, hãy nói về con trỏ. Đừng để từ này làm bạn sợ hãi - con trỏ chỉ là các biến lưu trữ địa chỉ bộ nhớ của biến khác. Chúng đặc biệt hữu ích với các cấu trúc khi chúng ta muốn thay đổi dữ liệu gốc.

Dưới đây là một ví dụ:

func updateEmail(c *Contact, newEmail string) {
c.Email = newEmail
}

func main() {
myFriend := Contact{
Name:        "Charlie",
PhoneNumber: "111-222-3333",
Email:       "[email protected]",
}

fmt.Println("Before update:", myFriend.Email)
updateEmail(&myFriend, "[email protected]")
fmt.Println("After update:", myFriend.Email)
}

Hãy phân tích điều này:

  1. Chúng ta định nghĩa updateEmail nhận một con trỏ đến Contact và một địa chỉ email mới
  2. Trong main(), chúng ta tạo một Contact mới cho Charlie
  3. Chúng ta in email ban đầu của Charlie
  4. Chúng ta gọi updateEmail, truyền địa chỉ của myFriend và email mới
  5. Chúng ta in email của Charlie một lần nữa để thấy sự thay đổi

Dấu & trước myFriend trong lời gọi hàm cho chúng ta địa chỉ bộ nhớ của myFriend, điều mà con trỏ trong updateEmail cần.

Sử dụng con trỏ cho phép chúng ta thay đổi Contact gốc trực tiếp, thay vì làm việc với một bản sao.

Phương thức trong Go

Dưới đây là bảng một số phương thức phổ biến được sử dụng với cấu trúc trong Go:

Phương thức Mô tả Ví dụ
Định nghĩa Định nghĩa một phương thức trên cấu trúc func (c Contact) FullName() string
Đối tượng nhận Cấu trúc mà phương thức liên kết với (c Contact) trong ví dụ trên
Con trỏ nhận Cho phép phương thức thay đổi cấu trúc func (c *Contact) UpdateEmail(newEmail string)
Gọi phương thức Cách gọi phương thức trên cấu trúc myFriend.FullName()

Kết luận

Chúc mừng! Bạn đã刚刚 bước vào thế giới của các cấu trúc trong Go. Chúng ta đã covers định nghĩa cấu trúc, truy cập các thành viên, sử dụng chúng với các hàm, và thậm chí đã thử nghiệm với con trỏ.

Nhớ rằng, học lập trình giống như học một ngôn ngữ mới - nó đòi hỏi sự luyện tập và kiên nhẫn. Đừng nản lòng nếu mọi thứ không ngay lập tức rõ ràng. Hãy tiếp tục thử nghiệm với các khái niệm này, thử tạo ra các cấu trúc của riêng bạn, và quan trọng nhất, hãy vui vẻ với nó!

Trong những năm dạy học của tôi, tôi đã phát hiện ra rằng những sinh viên tận hưởng quá trình học tập thường trở thành những nhà lập trình giỏi nhất. Vậy, hãy đón nhận thử thách,庆祝 chiến thắng (dù nhỏ), và tiếp tục lập mã!

Đến gặp lại lần sau, chúc các bạn thành công với Go!

Credits: Image by storyset