Trong Go, struct (viết tắt của structure) là một kiểu dữ liệu do người dùng định nghĩa, cho phép nhóm các giá trị có kiểu dữ liệu khác nhau vào một đơn vị duy nhất. Struct rất hữu ích trong việc tổ chức và quản lý dữ liệu phức tạp, giúp mã nguồn trở nên rõ ràng và dễ bảo trì hơn. Bài viết này sẽ cung cấp một cái nhìn tổng quan chi tiết về struct trong Go, bao gồm cú pháp, cách sử dụng, và các ví dụ minh họa cụ thể.
Khái Niệm Struct
Struct trong Go là một kiểu dữ liệu tổng hợp, cho phép bạn nhóm các giá trị có kiểu dữ liệu khác nhau vào một đơn vị duy nhất. Struct có thể được so sánh với các lớp (class) trong lập trình hướng đối tượng, nhưng Go không hỗ trợ kế thừa (inheritance) mà thay vào đó sử dụng thành phần (composition).
Cú Pháp Khai Báo Struct
Để khai báo một struct trong Go, bạn sử dụng từ khóa type
và struct
. Cú pháp cơ bản như sau:
type StructName struct {
field1 Type1
field2 Type2
// ...
}
Trong đó:
StructName
là tên của struct.field1
,field2
, ... là các trường (field) của struct, mỗi trường có một tên và một kiểu dữ liệu.
Ví Dụ Khai Báo Struct
Dưới đây là một ví dụ về cách khai báo một struct Person
với các trường name
, age
, job
, và salary
:
package main
import "fmt"
type Person struct {
name string
age int
job string
salary int
}
func main() {
// Tạo một instance của struct Person
var pers1 Person
var pers2 Person
// Gán giá trị cho các trường của pers1
pers1.name = "Hege"
pers1.age = 45
pers1.job = "Teacher"
pers1.salary = 6000
// Gán giá trị cho các trường của pers2
pers2.name = "Cecilie"
pers2.age = 24
pers2.job = "Marketing"
pers2.salary = 4500
// In ra thông tin của pers1
fmt.Println("Name: ", pers1.name)
fmt.Println("Age: ", pers1.age)
fmt.Println("Job: ", pers1.job)
fmt.Println("Salary: ", pers1.salary)
// In ra thông tin của pers2
fmt.Println("Name: ", pers2.name)
fmt.Println("Age: ", pers2.age)
fmt.Println("Job: ", pers2.job)
fmt.Println("Salary: ", pers2.salary)
}
Khởi Tạo Struct
Có nhiều cách để khởi tạo một struct trong Go. Bạn có thể khởi tạo struct bằng cách sử dụng cú pháp struct literal hoặc sử dụng từ khóa new
.
Sử Dụng Struct Literal
Struct literal cho phép bạn khởi tạo và gán giá trị cho các trường của struct trong một dòng mã.
Ví Dụ:
package main
import "fmt"
type Person struct {
name string
age int
job string
salary int
}
func main() {
// Khởi tạo struct bằng struct literal
pers1 := Person{"Hege", 45, "Teacher", 6000}
pers2 := Person{name: "Cecilie", age: 24, job: "Marketing", salary: 4500}
// In ra thông tin của pers1
fmt.Println("Name: ", pers1.name)
fmt.Println("Age: ", pers1.age)
fmt.Println("Job: ", pers1.job)
fmt.Println("Salary: ", pers1.salary)
// In ra thông tin của pers2
fmt.Println("Name: ", pers2.name)
fmt.Println("Age: ", pers2.age)
fmt.Println("Job: ", pers2.job)
fmt.Println("Salary: ", pers2.salary)
}
Sử Dụng Từ Khóa new
Từ khóa new
trong Go tạo ra một vùng nhớ mới cho struct và trả về một con trỏ tới vùng nhớ đó.
Ví Dụ:
package main
import "fmt"
type Person struct {
name string
age int
job string
salary int
}
func main() {
// Khởi tạo struct bằng từ khóa new
pers1 := new(Person)
pers1.name = "Hege"
pers1.age = 45
pers1.job = "Teacher"
pers1.salary = 6000
// In ra thông tin của pers1
fmt.Println("Name: ", pers1.name)
fmt.Println("Age: ", pers1.age)
fmt.Println("Job: ", pers1.job)
fmt.Println("Salary: ", pers1.salary)
}
Truy Cập và Thay Đổi Trường của Struct
Bạn có thể truy cập và thay đổi các trường của struct bằng cách sử dụng toán tử dấu chấm (.
).
Ví Dụ:
package main
import "fmt"
type Person struct {
name string
age int
job string
salary int
}
func main() {
// Khởi tạo struct bằng struct literal
pers1 := Person{"Hege", 45, "Teacher", 6000}
// Truy cập và thay đổi các trường của struct
fmt.Println("Name: ", pers1.name)
pers1.age = 46
fmt.Println("Updated Age: ", pers1.age)
}
Truyền Struct Làm Tham Số Hàm
Bạn có thể truyền struct làm tham số cho hàm. Struct có thể được truyền bằng giá trị hoặc bằng con trỏ.
Truyền Bằng Giá Trị
Khi truyền struct bằng giá trị, một bản sao của struct sẽ được tạo ra và truyền vào hàm.
Ví Dụ:
package main
import "fmt"
type Person struct {
name string
age int
job string
salary int
}
func printPerson(pers Person) {
fmt.Println("Name: ", pers.name)
fmt.Println("Age: ", pers.age)
fmt.Println("Job: ", pers.job)
fmt.Println("Salary: ", pers.salary)
}
func main() {
pers1 := Person{"Hege", 45, "Teacher", 6000}
printPerson(pers1)
}
Truyền Bằng Con Trỏ
Khi truyền struct bằng con trỏ, địa chỉ của struct sẽ được truyền vào hàm, cho phép hàm thay đổi giá trị của struct gốc.
Ví Dụ:
package main
import "fmt"
type Person struct {
name string
age int
job string
salary int
}
func updateAge(pers *Person, newAge int) {
pers.age = newAge
}
func main() {
pers1 := Person{"Hege", 45, "Teacher", 6000}
fmt.Println("Before update: ", pers1.age)
updateAge(&pers1, 46)
fmt.Println("After update: ", pers1.age)
}
Struct Lồng Nhau
Go cho phép bạn lồng các struct bên trong các struct khác, giúp tổ chức dữ liệu phức tạp hơn.
Ví Dụ:
package main
import "fmt"
type Address struct {
city string
state string
pincode int
}
type Person struct {
name string
age int
job string
salary int
address Address
}
func main() {
pers1 := Person{
name: "Hege",
age: 45,
job: "Teacher",
salary: 6000,
address: Address{
city: "Oslo",
state: "Oslo",
pincode: 1234,
},
}
fmt.Println("Name: ", pers1.name)
fmt.Println("City: ", pers1.address.city)
fmt.Println("State: ", pers1.address.state)
fmt.Println("Pincode: ", pers1.address.pincode)
}
Struct Ẩn Danh
Go cho phép bạn sử dụng struct ẩn danh, tức là struct không có tên, để tạo ra các kiểu dữ liệu tạm thời.
Ví Dụ:
package main
import "fmt"
func main() {
// Khởi tạo struct ẩn danh
person := struct {
name string
age int
}{
name: "Hege",
age: 45,
}
fmt.Println("Name: ", person.name)
fmt.Println("Age: ", person.age)
}
Kết Luận
Struct là một công cụ mạnh mẽ và linh hoạt trong Go, cho phép bạn tổ chức và quản lý dữ liệu phức tạp một cách hiệu quả. Bài viết này đã cung cấp một cái nhìn tổng quan chi tiết về struct trong Go, bao gồm cú pháp, cách sử dụng, và các ví dụ minh họa cụ thể. Hiểu rõ về struct sẽ giúp bạn viết mã Go hiệu quả và dễ bảo trì hơn.