- vừa được xem lúc

Phần 3: Khám phá golang - Kiểm soát luồng (Flow control statements)

0 0 14

Người đăng: Công Lâm

Theo Viblo Asia

Giới thiệu

Kiểm soát luồng(Flow control statements) đóng vai trò quan trọng trong việc điều chỉnh cách thức thực thi của chương trình. Trong ngôn ngữ lập trình Go, có một số lệnh kiểm soát luồng cơ bản như for, if-else, switchdefer được sử dụng để quản lý luồng của chương trình. Phần này sẽ giúp bạn hiểu rõ hơn về cách sử dụng các lệnh này để viết mã Go hiệu quả và có cấu trúc.
Chúng ta sẽ đi sâu vào từng loại lệnh kiểm soát luồng, xem cú pháp, cấu trúc và cách sử dụng chúng thông qua các ví dụ cụ thể. Điều này sẽ giúp bạn hiểu rõ cách sử dụng mỗi lệnh và làm thế nào để áp dụng chúng trong quy trình phát triển phần mềm của bạn.

Nội dung

Vòng lặp for

  • 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 có 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 vòng lặp đầ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 ở cuối 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 gọn, và các biến được khai báo ở đó chỉ có thể được nhìn thấy trong phạm vi của câu lệnh for.
    Vòng lặp sẽ dừng lặp khi biểu thức điều kiện đánh giá thành false.
    Lưu ý: Khác với các ngôn ngữ khác như C, Java hoặc JavaScript, không có dấu ngoặc đơn bao quanh ba thành phần của câu lệnh for và các dấu ngoặc nhọn { } luôn được yêu cầu.
    package main import "fmt" func main() { sum := 0 for i := 0; i < 10; i++ { sum += i } fmt.Println(sum)
    }
    
  • Câu lệnh init và câu lệnh post có thể có hoặc không(optional)

    package main import "fmt" func main() { sum := 1 for ; sum < 10; { fmt.Println(sum) sum += sum } fmt.Println(sum)
    }
    
  • Nếu loại bỏ luôn cả dấu chấm phẩy ở giữa các câu lệnh, nó sẽ giống "while" trong ngôn ngữ C

    package main import "fmt" func main() { sum := 1 for sum < 10 { sum += sum } fmt.Println(sum)
    }
    
  • Nếu bạn bỏ qua toàn bộ điều kiện, nó sẽ trở thành một vòng lặp vô hạn (và tất nhiên khi chạy sẽ lỗi "timeout running program" nếu chỉ có for không😄)

    package main func main() { for { }
    }
    
  • For-each range loop thường được sử dụng trong slices, arrays, maps, channels hoặc strings (Mình sẽ giới thiệu các loại dữ liệu này ở bài sau)

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

    Output:

    0 hello
    1 world
    
  • Exit a loop: Việc thoát khỏi vòng lặp của Go thì tương tự như cách làm của các ngôn ngữ khác như PHP, C hay Java, đó là dùng breakcontinue

If, If - else

  • Các câu lệnh if của Go giống như các vòng lặp for; biểu thức không cần phải được bao quanh bởi dấu ngoặc đơn ( ) nhưng bắt buộc phải có dấu ngoặc nhọn { }.

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

    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ũng có sẵn bên trong bất kỳ khối else nào.

    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

  • Một câu lệnh switch là cách viết ngắn gọn hơn để viết một chuỗi các câu lệnh if - else. Nó thực thi trường hợp đầu tiên mà giá trị của nó bằng 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, ngoại trừ rằng Go chỉ thực thi trường hợp được chọn, không phải tất cả các trường hợp tiếp theo. Trong thực tế, câu lệnh break cần thiết ở cuối mỗi trường hợp trong những ngôn ngữ đó được cung cấp tự động trong Go. Một điểm khác quan trọng khác là các trường hợp của switch trong Go không cần phải là hằng số, và các giá trị liên quan không cần phải là số nguyên.

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

    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: // freebsd, openbsd, // plan9, windows... fmt.Printf("%s.\n", os) }
    }
    
  • Switch không có điều kiện được gọi là switch true.Cấu trúc này có thể là một cách rõ ràng để viết các chuỗi if-then-else dài

    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à một khái niệm khá mới trong điều khiển luồng. Nó cho phép một câu lệnh được gọi ra nhưng không thực thi ngay mà hoãn lại đến khi các lệnh xung quanh trả về kết quả.
    package main import "fmt" func main() { defer fmt.Println("world") // Trì hoãn in ra chữ "world" fmt.Println("hello") // In ra chữ "hello"
    }
    
    Output:
     hello world
    
  • Các lệnh được gọi qua từ khóa defer sẽ được đưa vào một stack, tức là hoạt động theo cơ chế vào sau ra trước (last-in-first-out). Lệnh nào defer sau sẽ được thực thi trước, giống như xếp 1 chồng đĩa thì chiếc đĩa sau cùng (ở trên cùng) sẽ được lấy ra trước.
    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 biến i } fmt.Println("done")
    }
    
    Output:
    counting
    done
    9
    8
    7
    6
    5
    4
    3
    2
    1
    0
    

Kết bài

Trong bài thứ 3 này mình đã giới thiệu với các bạn những khái niệm cơ bản cũng như quan trọng nhất về Flow control statements trong golang. Bài tới mình sẽ giới thiệu về các types: structs, slices, and maps 😄
Nếu có thắc mắc hoặc phát hiện bài viết có thiếu sót gì, hãy comment cho mình biết để mình kịp thời chỉnh sửa cũng như cùng thảo luận về thắc mắc đó nhé 😉
Hi vọng những kiến thức này sẽ giúp ích được các bạn trong hành trình chinh phục Golang. Hẹn gặp lại ở những bài viết tiếp theo trong series Golang Essentials: Nền Tảng và Kiến Thức Cơ Bản. See ya!

Tham khảo: https://go.dev/tour/flowcontrol

Bình luận

Bài viết tương tự

- vừa được xem lúc

gRPC - Nó là gì và có nên sử dụng hay không?

Nhân một ngày rảnh rỗi, mình ngồi đọc lại RPC cũng như gRPC viết lại để nhớ lâu hơn. Vấn đề là gì và tại sao cần nó .

0 0 131

- vừa được xem lúc

Embedded Template in Go

Getting Start. Part of developing a web application usually revolves around working with HTML as user interface.

0 0 56

- vừa được xem lúc

Tạo Resful API đơn giản với Echo framework và MySQL

1. Giới thiệu.

0 0 60

- vừa được xem lúc

Sử dụng goquery trong golang để crawler thông tin các website Việt Nam bị deface trên mirror-h.org

. Trong bài viết này, mình sẽ cùng mọi người khám phá một package thu thập dữ liệu có tên là goquery của golang. Mục tiêu chính của chương trình crawler này sẽ là lấy thông tin các website Việt Nam bị deface (là tấn công, phá hoại website, làm thay đổi giao diện hiển thị của một trang web, khi người

0 0 237

- vừa được xem lúc

Tạo ứng dụng craw dữ liệu bing với Golang, Mysql driver

Chào mọi người . Lâu lâu ta lại gặp nhau 1 lần, để tiếp tục series chia sẻ kiến thức về tech, hôm nay mình sẽ tìm hiểu và chia sẻ về 1 ngôn ngữ đang khá hot trong cộng đồng IT đó là Golang.

0 0 75

- vừa được xem lúc

Golang: Rest api and routing using MUX

Routing with MUX. Let's create a simple CRUD api for a blog site. # All . GET articles/ .

0 0 54