Trong ngôn ngữ Go, không có từ khóa foreach như trong một số ngôn ngữ khác, nhưng bạn có thể sử dụng vòng lặp for kết hợp với từ khóa range để đạt được chức năng tương tự. Vòng lặp for ... range trong Go được sử dụng để lặp qua các phần tử của một mảng, lát cắt (slice), bản đồ (map), chuỗi (string), hoặc kênh (channel).

Dưới đây là cách sử dụng for ... range để thay thế cho foreach trong các cấu trúc dữ liệu khác nhau:

1. for ... range với mảng (array) và lát cắt (slice)

Khi sử dụng với mảng hoặc lát cắt, range trả về cả chỉ số (index) và giá trị (value) của từng phần tử trong mảng hoặc lát cắt.

Ví dụ:

package main

import "fmt"

func main() {
    numbers := []int{1, 2, 3, 4, 5}

    // Duyệt qua lát cắt (slice)
    for index, value := range numbers {
        fmt.Printf("Chỉ số: %d, Giá trị: %dn", index, value)
    }
}

Kết quả:

Chỉ số: 0, Giá trị: 1
Chỉ số: 1, Giá trị: 2
Chỉ số: 2, Giá trị: 3
Chỉ số: 3, Giá trị: 4
Chỉ số: 4, Giá trị: 5

Nếu bạn chỉ cần giá trị và không cần chỉ số, bạn có thể bỏ qua chỉ số bằng cách sử dụng dấu gạch dưới (_):

for _, value := range numbers {
    fmt.Println("Giá trị:", value)
}

2. for ... range với bản đồ (map)

Khi sử dụng với bản đồ (map), range trả về cả khóa (key) và giá trị (value) của từng cặp trong bản đồ.

Ví dụ:

package main

import "fmt"

func main() {
    capitals := map[string]string{"Vietnam": "Hanoi", "Japan": "Tokyo", "France": "Paris"}

    // Duyệt qua map
    for country, capital := range capitals {
        fmt.Printf("Quốc gia: %s, Thủ đô: %sn", country, capital)
    }
}

Kết quả:

Quốc gia: Vietnam, Thủ đô: Hanoi Quốc gia: Japan, Thủ đô: Tokyo Quốc gia: France, Thủ đô: Paris

3. for ... range với chuỗi (string)

Khi sử dụng với chuỗi (string), range trả về cả chỉ số của ký tự và giá trị mã Unicode (rune) của ký tự đó.

Ví dụ:

package main

import "fmt"

func main() {
    str := "Xin chào"

    // Duyệt qua chuỗi
    for index, runeValue := range str {
        fmt.Printf("Chỉ số: %d, Rune: %cn", index, runeValue)
    }
}

Kết quả:

Chỉ số: 0, Rune: X
Chỉ số: 1, Rune: i
Chỉ số: 2, Rune: n
Chỉ số: 3, Rune:  
Chỉ số: 4, Rune: c
Chỉ số: 5, Rune: h
Chỉ số: 6, Rune: à
Chỉ số: 8, Rune: o

Lưu ý rằng trong ví dụ này, ký tự à chiếm hai byte, vì vậy chỉ số tiếp theo là 8, không phải 7.

4. for ... range với kênh (channel)

Với kênh (channel), range được sử dụng để lặp qua các giá trị được gửi vào kênh cho đến khi kênh bị đóng.

Ví dụ:

package main

import "fmt"

func main() {
    ch := make(chan int)

    // Khởi động một goroutine để gửi dữ liệu vào kênh
    go func() {
        for i := 1; i

Kết quả:

Nhận giá trị từ kênh: 1
Nhận giá trị từ kênh: 2
Nhận giá trị từ kênh: 3
Nhận giá trị từ kênh: 4
Nhận giá trị từ kênh: 5

Tóm tắt:

  • for ... range trong Go là cách thay thế cho foreach.
  • Sử dụng với mảnglát cắt: trả về chỉ số và giá trị của từng phần tử.
  • Sử dụng với bản đồ (map): trả về khóa và giá trị của từng cặp.
  • Sử dụng với chuỗi (string): trả về chỉ số và giá trị mã Unicode (rune).
  • Sử dụng với kênh (channel): nhận giá trị từ kênh cho đến khi kênh bị đóng.

Cấu trúc for ... range là một cách linh hoạt và hiệu quả để lặp qua các loại dữ liệu khác nhau trong Go.