0
0
Lập trình
Admin Team
Admin Teamtechmely

Phần 3: Khám Phá Ngôn Ngữ Go Qua Các Câu Lệnh Kiểm Soát Luồng

Đăng vào 2 ngày trước

• 8 phút đọc

Chủ đề:

golangMayFest2024

Giới thiệu

Kiểm soát luồng (Flow control statements) là những yếu tố thiết yếu trong ngôn ngữ lập trình Go giúp điều chỉnh cách thức thực thi của chương trình. Các câu lệnh kiểm soát luồng phổ biến trong Go bao gồm for, if-else, switch, và defer. Bài viết này sẽ hướng dẫn bạn cách sử dụng các lệnh này để viết mã Go một cách hiệu quả và có cấu trúc.

Chúng ta sẽ cùng tìm hiểu từng loại lệnh kiểm soát luồng, với cú pháp, cấu trúc, và ứng dụng thông qua những ví dụ cụ thể. Điều này sẽ giúp bạn hiểu được cách áp dụng các lệnh này trong quy trình phát triển phần mềm của mình.

Nội dung

Vòng lặp for

  • Ngôn ngữ Go chỉ có một cấu trúc vòng lặp, đó là vòng lặp for. Vòng lặp for cơ bản bao gồm ba thành phần được phân tách bởi dấu chấm phẩy:
  1. Câu lệnh init: Được thực thi trước khi vòng lặp bắt đầu lần đầu tiên.
  2. Biểu thức điều kiện: Được đánh giá trước mỗi lần lặp.
  3. Câu lệnh post: Được thực thi sau mỗi lần lặp.
    Câu lệnh init thường là một câu khai báo biến ngắn, và các biến này chỉ có thể được sử dụng trong phạm vi vòng lặp for.
    Vòng lặp sẽ dừng khi biểu thức điều kiện trả về false.

Lưu ý: Khác với các ngôn ngữ khác như C, Java, hoặc JavaScript, Go không yêu cầu dấu ngoặc đơn cho ba thành phần của câu lệnh for, nhưng dấu ngoặc nhọn { } là điều bắt buộc.

go Copy
package main

import "fmt"

func main() {
    sum := 0
    for i := 0; i < 10; i++ {
        sum += i
    }
    fmt.Println(sum)
}
  • Câu lệnh initcâu lệnh post có thể không xuất hiện:

    go Copy
    package main
    
    import "fmt"
    
    func main() {
        sum := 1
        for ; sum < 10; {
            fmt.Println(sum)
            sum += sum
        }
        fmt.Println(sum)
    }
  • Nếu bỏ luôn cả dấu chấm phẩy, vòng lặp sẽ trông giống như một câu lệnh while trong ngôn ngữ C:

    go Copy
    package main
    
    import "fmt"
    
    func main() {
        sum := 1
        for sum < 10 {
            sum += sum
        }
        fmt.Println(sum)
    }
  • Nếu bỏ qua toàn bộ điều kiện, vòng lặp sẽ trở thành vòng lặp vô hạn:

    go Copy
    package main
    
    func main() {
        for {
        }
    }
  • For-each range loop thường được sử dụng với slices, arrays, maps, channels, hoặc strings:

    go Copy
    strings := []string{"hello", "world"}
    for i, s := range strings {
        fmt.Println(i, s)
    }

    Output:

    Copy
    0 hello
    1 world
  • Để thoát khỏi vòng lặp, bạn có thể sử dụng breakcontinue, tương tự như trong các ngôn ngữ khác như PHP, C, hoặc Java.

If, If - else

  • Câu lệnh if trong Go tương tự như vòng lặp for; không cần có dấu ngoặc đơn ( ) nhưng bắt buộc phải có dấu ngoặc nhọn { }.

    go Copy
    func sqrt(x float64) string {
        if x < 0 {
            return sqrt(-x) + "i"
        }
        return fmt.Sprint(math.Sqrt(x))
    }
  • Tương tự như for, if cũng có thể bắt đầu bằng một câu lệnh ngắn (short statement) được thực thi trước khi kiểm tra điều kiện:

    go Copy
    func pow(x, n, lim float64) float64 {
        if v := math.Pow(x, n); v < lim {
            return v
        }
        return lim
    }
  • If và else: Các biến được khai báo bên trong câu lệnh if short statement có thể được sử dụng trong bất kỳ khối else nào:

    go Copy
    func pow(x, n, lim float64) float64 {
        if v := math.Pow(x, n); v < lim {
            return v
        } else {
            fmt.Printf("%g >= %g\n", v, lim)
        }
        // không thể sử dụng biến v ở đây
        return lim
    }

Switch - Case

  • Câu lệnh switch là cách viết ngắn gọn hơn cho một chuỗi các câu lệnh if - else. Nó sẽ thực hiện trường hợp đầu tiên mà giá trị của nó khớp với biểu thức điều kiện.

  • Câu lệnh switch trong Go tương tự như trong C, C++, Java, JavaScript, và PHP, nhưng Go chỉ thực thi trường hợp được chọn và không cần phải dùng câu lệnh break ở cuối mỗi trường hợp.

  • Các trường hợp trong switch được đánh giá từ trên xuống dưới, dừng lại khi một trường hợp trở thành đúng:

    go Copy
    package main
    
    import (
        "fmt"
        "runtime"
    )
    
    func main() {
        fmt.Print("Go runs on ")
        switch os := runtime.GOOS; os {
        case "darwin":
            fmt.Println("OS X.")
        case "linux":
            fmt.Println("Linux.")
        default:
            fmt.Printf("%s.\n", os)
        }
    }
  • Switch không có điều kiện còn được gọi là switch true, phù hợp để viết các chuỗi if-then-else dài một cách rõ ràng:

    go Copy
    package main
    
    import (
        "fmt"
        "time"
    )
    
    func main() {
        t := time.Now()
        switch {
        case t.Hour() < 12:
            fmt.Println("Good morning!")
        case t.Hour() < 17:
            fmt.Println("Good afternoon.")
        default:
            fmt.Println("Good evening.")
        }
    }

Defer

  • Trì hoãn (defer) là khái niệm độc đáo trong kiểm soát luồng. Nó cho phép một câu lệnh được chỉ định nhưng sẽ không thực thi ngay lập tức, mà sẽ được hoãn lại cho đến khi hàm chứa nó trả về.

    go Copy
    package main
    
    import "fmt"
    
    func main() {
        defer fmt.Println("world")   // Hoãn in ra chữ "world"
        fmt.Println("hello")          // In ra chữ "hello"
    }

    Output:

    Copy
    hello
    world
  • Các câu lệnh được defer sẽ được xếp vào một stack, hoạt động theo cơ chế sau trước ra trước (last-in-first-out). Câu lệnh nào được defer sau sẽ được thực thi trước:

    go Copy
    package main
    
    import "fmt"
    
    func main() {
        fmt.Println("counting")
        for i := 0; i < 10; i++ {
            defer fmt.Println(i)   // In ra giá trị của i
        }
        fmt.Println("done")
    }

    Output:

    Copy
    counting
    done
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0

Kết bài

Trong bài viết thứ 3 này, tôi đã giới thiệu những khái niệm cơ bản nhưng quan trọng nhất về các câu lệnh kiểm soát luồng trong ngôn ngữ Go. Ở bài tiếp theo, tôi sẽ cùng bạn khám phá các kiểu dữ liệu như pointer, structs, slices, và maps. 😊

Nếu bạn có thắc mắc hoặc phát hiện nội dung thiếu sót trong bài viết, xin hãy để lại câu hỏi để chúng ta cùng thảo luận và chỉnh sửa cho phù hợp. Hy vọng những kiến thức này sẽ hỗ trợ bạn trong hành trình chinh phục ngôn ngữ Go. Hẹn gặp lại trong các bài viết tiếp theo trong series Golang Essentials: Nền Tảng và Kiến Thức Cơ Bản.
source: viblo

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào