Học Go cấp tốc Phần 2: Điều khiển luồng với if, else, switch và defer



  • Tiếp theo Học Go cấp tốc Phần 1: Packages, Variables và Functions.

     

    Phần tiếp theo chúng ta sẽ cùng tìm hiểu cách điều khiển luồng (flow control) trong Go.

     

    Vòng lặp

    - Trong Go chỉ có 1 kiểu vòng lặp là sử dụng for. Cách dùng tương tự các ngôn ngữ khác nhưng phần khai báo biến, điều kiện lặp, ... không cần đặt trong cặp ngoặc tròn: 

    // Tính tổng các số từ 0 - 9
    sum := 0
    for i := 0; i < 10; i++ {
        sum += i
    }
    fmt.Println(sum)

     

    - Vòng lặp for khi chỉ có điều kiện lặp thì hoạt động giống while trong các ngôn ngữ khác: 

    sum := 0
    for sum < 10 {
        sum += sum
    }
    fmt.Println(sum)

     

    Điều kiện

    - Lệnh điều kiện trong Go sử dụng if, else, switch, và cũng như vòng lặp for chúng ta không cần cặp ngoặc tròn.

    - Với câu lệnh if chúng ta có thể khai báo biến ngay trong câu lệnh điều kiện, và biến này sẽ chỉ hoạt động ở trong block của lệnh if hoặc else

    import (
        "fmt"
        "math"
    )
    
    func pow(x, n, limit float64) float64 {
        // Khai báo biến v trong lệnh điều kiện của if sẽ chỉ sử dụng được trong block if hoặc else
        if v := math.Pow(x, n); v < limit {
            return v
        } else {
            fmt.Printf("%g >= %g\n", v, limit)
    	}
    
    	// Không sử dụng được biến v ở bên ngoài, ví dụ return v sẽ báo lỗi
    	return lim
    }
    

     

    - Lệnh switch tương tự các ngôn ngữ khác, tuy nhiên có một số điểm khác biệt:

    • Biểu thức trong switch không được sử dụng hằng số (constant).
    • Không cần lệnh break trong mỗi case (mặc định các case tự break). Do đó chỉ có trường hợp thỏa mãn đầu tiên được chạy (tính từ trên xuống dưới). Ví dụ: 
      switch num := 10; {
          case num < 50:
              fmt.Printf("%d < 50\n", num)   // In ra 10 < 50
          case num < 100:
              fmt.Printf("%d < 100\n", num)  // Lệnh này không chạy mặc dù cũng thỏa mãn điều kiện
          default:
              fmt.Printf("I don't know", num)
      }
    • Có thể sử dụng nhiều điều kiện trong một case, hoặc sử dụng từ khóa fallthrough để cho phép chạy tiếp xuống câu lệnh tiếp theo: 
      num := 10;
      

      switch { // Tương đương với switch true
      case num >= 0 && num <= 50:
      fmt.Printf("%d < 50 \n", num) // In ra 10 < 50
      fallthrough
      case num < 100:
      fmt.Printf("%d < 100 \n", num) // In ra 10 < 100
      default:
      fmt.Printf("I don't know", num)
      }


     

    Trì hoãn

    - Trì hoãn (defer) là một khái niệm khá mới trong điều khiển luồng dữ liệu. 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ả. Ví dụ: 

    package main
    
    import "fmt"
    
    func main() {
        defer fmt.Println("World")   // Hoãn lệnh in ra chữ "World"
        fmt.Println("Hello")   //   Kết quả in ra "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. Ví dụ: 

    package main
    
    import "fmt"
    
    func main() {
        for i := 0; i < 10; i++ {
            defer fmt.Println(i)   // In ra giá trị của biến i
        }
    
        // Kết quả trả về ngược so với vòng lặp: 
        // 9 8 7 6 5 4 3 2 1 0
    }

    Chú ý là khi gọi lệnh defer thì giá trị của biến trong câu lệnh sẽ là giá trị tại thời điểm gọi chứ không phải giá trị tại thời điểm thực thi.


Hãy đăng nhập để trả lời
 

Có vẻ như bạn đã mất kết nối tới LaptrinhX, vui lòng đợi một lúc để chúng tôi thử kết nối lại.