Lệnh vòng lặp trong Go

Một câu lệnh lặp được sử dụng để thực thi lặp lại một khối mã.

Lệnh for là vòng lặp duy nhất có sẵn trong Go. Go không có vòng lặp while hoặc do while có trong các ngôn ngữ khác như C, C++, C#, Java, ...

Trong hướng dẫn này chúng ta sẽ tìm hiểu về cách khai báo vòng lặp for, lệnh break, lệnh continue, nhãn, và các biến thể khác của vòng lặp for trong Go.

Cú pháp vòng lặp for

for initialisation; condition; post {  
}

Câu lệnh khởi tạo sẽ chỉ được thực hiện một lần. Sau khi vòng lặp được khởi tạo, điều kiện sẽ được kiểm tra. Nếu điều kiện đánh giá là true, phần thân của vòng lặp bên trong cặp dấu ngoặc ngọn { } sẽ được thực thi theo sau là câu lệnh post. Câu lệnh post sẽ được thực thi sau mỗi lần lặp lại vòng lặp thành công. Sau khi câu lệnh post được thực thi, điều kiện sẽ được kiểm tra lại. Nếu đúng, vòng lặp sẽ tiếp tục thực thi, nếu không, vòng lặp for sẽ kết thúc.

Tất cả ba thành phần cụ thể là initialisation, condition post là tùy chọn trong Go. Hãy xem một ví dụ để hiểu rõ hơn về vòng lặp for.

Ví dụ về vòng lặp for trong Go

Hãy viết một chương trình sử dụng vòng lặp for để in tất cả các số từ 1 đến 10.

package main

import (  
    "fmt"
)

func main() {  
    for i := 1; i <= 10; i++ {
        fmt.Printf(" %d",i)
    }
}

Chạy chương trình trong Playground

Trong chương trình trên, i được khởi tạo bằng 1. Câu lệnh điều kiện sẽ kiểm tra nếu i <= 10. Nếu điều kiện là đúng, giá trị của i được in ra, nếu không thì vòng lặp bị kết thúc. Câu lệnh post tăng i lên 1 ở cuối mỗi lần lặp. Khi i lớn hơn 10, vòng lặp kết thúc.

Chương trình trên sẽ in ra kết quả sau:

1 2 3 4 5 6 7 8 9 10

Các biến được khai báo trong vòng lặp for chỉ khả dụng trong phạm vi của vòng lặp. Do đó biến i không thể truy cập bên ngoài phần thân của vòng lặp for.

Câu lệnh break

Câu lệnh break được sử dụng để kết thúc vòng lặp for một cách đột ngột trước khi nó kết thúc quá trình thực thi bình thường và chuyển điều khiển đến dòng mã ngay sau vòng lặp for.

Hãy viết một chương trình in các số từ 1 đến 5 bằng cách sử dụng break.

package main

import (  
    "fmt"
)

func main() {  
    for i := 1; i <= 10; i++ {
        if i > 5 {
            break //loop is terminated if i > 5
        }
        fmt.Printf("%d ", i)
    }
    fmt.Printf("\nline after for loop")
}

Chạy chương trình trong Playground

Trong chương trình trên, giá trị của i được kiểm tra trong mỗi lần lặp. Nếu i lớn hơn 5 thì thực thi lệnh break và vòng lặp kết thúc. Sau đó, câu lệnh print ngay sau vòng lặp for được thực thi. Chương trình trên sẽ xuất ra kết quả sau:

1 2 3 4 5  
line after for loop  

Câu lệnh continue

Câu lệnh continue được sử dụng để bỏ qua lần lặp hiện tại của vòng lặp for. Tất cả mã có trong vòng lặp for sau câu lệnh continue sẽ không được thực thi cho lần lặp hiện tại. Vòng lặp sẽ chuyển sang lần lặp tiếp theo.

Hãy viết một chương trình để in tất cả các số lẻ từ 1 đến 10 bằng cách sử dụng continue.

package main

import (  
    "fmt"
)

func main() {  
    for i := 1; i <= 10; i++ {
        if i%2 == 0 {
            continue
        }
        fmt.Printf("%d ", i)
    }
}

Chạy chương trình trong Playground

Trong chương trình trên, dòng if i%2 == 0 sẽ kiểm tra xem phần dư của phép chia i cho 2 có bằng 0 hay không. Nếu nó bằng 0, thì số đó là số chẵn và câu lệnh continue được thực hiện và điều khiển chuyển sang lần lặp tiếp theo của vòng lặp. Do đó, câu lệnh print sau bước continue sẽ không được gọi và vòng lặp chuyển sang lần lặp tiếp theo. Đầu ra của chương trình trên là

1 3 5 7 9

Vòng lặp lồng nhau

Một vòng lặp for có một vòng lặp for khác bên trong nó được gọi là vòng lặp for lồng nhau.

Hãy hiểu các vòng lặp for lồng nhau bằng cách viết một chương trình in ra chuỗi bên dưới.

*
**
***
****
*****

Chương trình dưới đây sử dụng các vòng lặp for lồng nhau để in chuỗi. Biến n ở dòng số 8 lưu trữ số dòng trong dãy. Trong trường hợp của chúng ta, đó là 5. Vòng lặp for bên ngoài lặp lại i từ 0 đến 4 và vòng lặp for bên trong lặp lại j từ 0 giá trị hiện tại của i. Vòng lặp bên trong in ra dấu * cho mỗi lần lặp và vòng lặp bên ngoài in một dòng mới ở cuối mỗi lần lặp. Chạy chương trình này và bạn thấy trình tự được in dưới dạng đầu ra.

package main

import (  
    "fmt"
)

func main() {  
    n := 5
    for i := 0; i < n; i++ {
        for j := 0; j <= i; j++ {
            fmt.Print("*")
        }
        fmt.Println()
    }
}

Chạy chương trình trong Playground

Nhãn trong Go

Nhãn (label) có thể được sử dụng để phá vỡ vòng lặp bên ngoài từ bên trong vòng lặp for bên trong. Hãy hiểu ý tôi bằng cách sử dụng một ví dụ đơn giản.

package main

import (  
    "fmt"
)

func main() {  
    for i := 0; i < 3; i++ {
        for j := 1; j < 4; j++ {
            fmt.Printf("i = %d , j = %d\n", i, j)
        }

    }
}

Chạy chương trình trong Playground

Chương trình trên sẽ in ra kết quả sau:

i = 0 , j = 1  
i = 0 , j = 2  
i = 0 , j = 3  
i = 1 , j = 1  
i = 1 , j = 2  
i = 1 , j = 3  
i = 2 , j = 1  
i = 2 , j = 2  
i = 2 , j = 3  

Không có gì đặc biệt trong này :)

Điều gì sẽ xảy ra nếu chúng ta muốn dừng in khi ij bằng nhau. Để làm điều này, chúng ta cần gọi lệnh break từ vòng lặp for bên ngoài . Thêm một break vào vòng lặp for bên trong khi ij bằng nhau sẽ chỉ ngắt khỏi vòng lặp for bên trong.

package main

import (  
    "fmt"
)

func main() {  
    for i := 0; i < 3; i++ {
        for j := 1; j < 4; j++ {
            fmt.Printf("i = %d , j = %d\n", i, j)
            if i == j {
                break
            }
        }

    }
}

Chạy chương trình trong Playground

Trong chương trình trên, tôi đã thêm lệnh break vào bên trong vòng lặp for khi ij bằng nhau ở dòng số 10. Lệnh break này sẽ chỉ từ vòng lặp for bên trong và vòng lặp for bên ngoài sẽ tiếp tục. Chương trình này sẽ in ra kết quả sau:

i = 0 , j = 1  
i = 0 , j = 2  
i = 0 , j = 3  
i = 1 , j = 1  
i = 2 , j = 1  
i = 2 , j = 2  

Đây không phải là đầu ra dự kiến. Chúng ta cần dừng in khi ij bằng nhau tức là khi chúng bằng 1.

Đây là nơi nhãn đến để giải cứu chúng ta. Một nhãn có thể được sử dụng để ngắt khỏi vòng lặp bên ngoài. Hãy viết lại chương trình trên bằng cách sử dụng nhãn.

package main

import (  
    "fmt"
)

func main() {  
outer:  
    for i := 0; i < 3; i++ {
        for j := 1; j < 4; j++ {
            fmt.Printf("i = %d , j = %d\n", i, j)
            if i == j {
                break outer
            }
        }

    }
}

Chạy chương trình trong Playground

Trong chương trình trên, chúng ta đã thêm nhãn outer ở dòng số 8 bên trên vòng lặp for bên ngoài và ở dòng số 13 chúng ta thoát vòng lặp for bên ngoài bằng cách chỉ định nhãn. Chương trình này sẽ ngừng in khi ijbằng nhau. Chương trình này sẽ xuất ra kết quả sau:

i = 0 , j = 1  
i = 0 , j = 2  
i = 0 , j = 3  
i = 1 , j = 1  

Các ví dụ khác

Hãy viết thêm một số mã để bao gồm tất cả các biến thể của vòng lặp for.

Chương trình dưới đây in tất cả các số chẵn từ 0 đến 10.

package main

import (  
    "fmt"
)

func main() {  
    i := 0
    for ;i <= 10; { // initialisation and post are omitted
        fmt.Printf("%d ", i)
        i += 2
    }
}

Chạy chương trình trong Playground

Như chúng ta đã biết tất cả ba thành phần của vòng lặp for là initialisation, condition post là tùy chọn. Trong chương trình trên, initialisationpost bị bỏ qua. Biến i được khởi tạo bằng 0 bên ngoài vòng lặp for. Vòng lặp sẽ được thực hiện miễn là i <= 10. Biến i được cộng thêm 2 bên trong vòng lặp for. Kết quả chương trình trên 0 2 4 6 8 10.

Các dấu chấm phẩy trong vòng lặp for của chương trình trên cũng có thể được bỏ qua. Định dạng này có thể được coi là một thay thế cho vòng lặp while. Chương trình trên có thể được viết lại thành,

package main

import (  
    "fmt"
)

func main() {  
    i := 0
    for i <= 10 { //semicolons are ommitted and only condition is present
        fmt.Printf("%d ", i)
        i += 2
    }
}

Chạy chương trình trong Playground

Có thể khai báo và thao tác trên nhiều biến trong vòng lặp for. Hãy viết một chương trình in ra chuỗi dưới đây bằng cách sử dụng nhiều khai báo biến.

10 * 1 = 10  
11 * 2 = 22  
12 * 3 = 36  
13 * 4 = 52  
14 * 5 = 70  
15 * 6 = 90  
16 * 7 = 112  
17 * 8 = 136  
18 * 9 = 162  
19 * 10 = 190  
package main

import (  
    "fmt"
)

func main() {  
    for no, i := 10, 1; i <= 10 && no <= 19; i, no = i+1, no+1 { //multiple initialisation and increment
        fmt.Printf("%d * %d = %d\n", no, i, no*i)
    }

}

Chạy chương trình trong Playground

Trong chương trình trên biến noi được khai báo và khởi tạo lần lượt là 10 và 1. Chúng được tăng thêm 1 vào cuối mỗi lần lặp. Toán tử boolean && được sử dụng trong điều kiện để đảm bảo rằng i nhỏ hơn hoặc bằng 10 và cũng no nhỏ hơn hoặc bằng 19.

Vòng lặp vô hạn

Cú pháp để tạo một vòng lặp vô hạn là,

for {  
}

Chương trình sau sẽ tiếp tục in Hello World liên tục mà không kết thúc.

package main

import "fmt"

func main() {  
    for {
        fmt.Println("Hello World")
    }
}

Nếu bạn cố gắng chạy chương trình trên trong Playground, bạn sẽ gặp lỗi "process took too long". Hãy thử chạy nó trong hệ thống cục bộ của bạn để in vô hạn "Hello World".

Có một cấu trúc range khác có thể được sử dụng trong vòng lặp for để thao tác với mảng. Chúng ta sẽ đề cập đến vấn đề này khi chúng ta tìm hiểu về mảng.

Hy vọng bạn thích bài viết này và cảm ơn vì bạn đã đọc. Vui lòng để lại ý kiến ​​và phản hồi có giá trị của bạn.

Nếu Comdy hữu ích và giúp bạn tiết kiệm thời gian làm việc

Bạn có thể vui lòng đưa Comdy vào whitelist của trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi trong việc trả tiền cho dịch vụ lưu trữ web để duy trì hoạt động của trang web.

Go
Bài Viết Liên Quan:
Phương thức (method) trong Go
Trung Nguyen 02/12/2021
Phương thức (method) trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu phương thức (method) trong Go là gì? Cú pháp khai báo phương thức, so sánh phương thức với hàm, ... trong Go.

Struct trong Go
Trung Nguyen 28/11/2021
Struct trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu struct là gì, cách khai báo và sử dụng một struct trong Go, struct ẩn danh, so sanh hai struct, ...

Con trỏ trong Go
Trung Nguyen 28/11/2021
Con trỏ trong Go

Trong hướng dẫn này, chúng ta sẽ tìm hiểu cách con trỏ (pointer) hoạt động trong Go và nó khác với con trỏ trong các ngôn ngữ khác như C và C++ như thế nào.

Chuỗi trong Go
Trung Nguyen 28/11/2021
Chuỗi trong Go

Chuỗi (string) xứng đáng được đề cập đặc biệt trong Go vì chúng khác biệt trong cách triển khai khi so sánh với các ngôn ngữ khác.