1. Tổng quan.
Câu lệnh switch trong ngôn ngữ lập trình Go được sử dụng để kiểm tra giá trị của một biểu thức và thực hiện các hành động tương ứng dựa trên giá trị đó. Nó giúp tạo ra một cách hiệu quả và dễ đọc để xử lý nhiều trường hợp khác nhau.
Ý nghĩa chính của câu lệnh switch là:
- Lựa chọn giữa nhiều trường hợp: Câu lệnh switch cho phép bạn xác định nhiều trường hợp (case) để kiểm tra giá trị của biểu thức và thực hiện code tương ứng với trường hợp nào khớp với giá trị.
- Giảm sự lặp lại: Khi có nhiều trường hợp cần kiểm tra, switch giúp giảm sự lặp lại code, vì bạn không cần phải sử dụng nhiều câu lệnh if-else nếu có nhiều giá trị để kiểm tra.
- Tính rõ ràng và dễ đọc: Switch tạo ra một cú pháp rõ ràng và dễ đọc, giúp làm cho code nguồn trở nên dễ hiểu hơn, đặc biệt khi có nhiều trường hợp cần xử lý.
- Tự động thoát sau mỗi case: Trong Go sau khi một case khớp, switch sẽ tự động thoát mà không cần sử dụng câu lệnh break như trong nhiều ngôn ngữ khác.
- Hỗ trợ Multi-case: Câu lệnh switch cũng hỗ trợ Multi-case cho phép kiểm tra giá trị của biểu thức với nhiều giá trị khác nhau trong một case.
- Switch Statement (Câu lệnh switch):
- Câu lệnh switch được sử dụng để chọn một trong nhiều khối code để thực thi.
- Nó giống với câu lệnh switch trong các ngôn ngữ lập trình như C, C++, Java, JavaScript và PHP.
- Hoạt động của Switch Statement:
- Khi bạn sử dụng câu lệnh switch, chương trình sẽ kiểm tra giá trị của một biểu thức (expression) so với nhiều case (trường hợp) có thể.
- Nếu giá trị của biểu thức khớp với một trong các case, code trong case đó sẽ được thực thi.
- Sự khác biệt quan trọng là sau khi một case khớp, câu lệnh switch trong Go không cần phải có một câu lệnh break để kết thúc switch. Trong nhiều ngôn ngữ khác, bạn cần sử dụng break để ngăn chặn việc thực thi các case phía sau case đã khớp. Trong Go, sau khi một case khớp, nó sẽ tự động thoát khỏi switch.
2. Cú pháp switch với single-case switch.
Cú pháp của câu lệnh switch với chỉ một trường hợp (single-case switch) trong ngôn ngữ Go.
switch expression {
case x:
// code
case y:
// code
case z:
// ...
default:
// code
}
- Cách hoạt động:
- Biểu thức (expression) được đánh giá một lần.
- Giá trị của biểu thức switch được so sánh với các giá trị của mỗi case.
- Nếu có sự khớp thì code tương ứng với case đó sẽ được thực thi.
- Tùy chọn là tùy chọn. Nó xác định một đoạn code để chạy nếu không có case nào khớp.
- Cách hoạt động chi tiết:
- Biểu thức switch được đánh giá.
- Giá trị của biểu thức switch được so sánh lần lượt với giá trị của mỗi case.
- Nếu có một case khớp, code bên trong case đó sẽ được thực thi. Sau đó, switch sẽ kết thúc và không kiểm tra các case phía sau nữa.
- Nếu không có case nào khớp và có một khối code default, code trong default sẽ được thực thi.
- Nếu không có khối code default, không có gì sẽ được thực thi nếu không có case nào khớp.
Chương trình dưới đây sử dụng câu lệnh switch
để kiểm tra giá trị của biến number
và in ra giá trị tương ứng. Trong trường hợp này, giá trị của number
là 2.
package main
import "fmt"
func main() {
number := 2
switch number {
case 1:
fmt.Println("One")
case 2:
fmt.Println("Two")
case 3:
fmt.Println("Three")
default:
fmt.Println("Other")
}
}
Vì vậy, chương trình sẽ thực hiện case 2 và in ra “Two”. Dưới đây là kết quả bạn sẽ nhận được khi chạy chương trình:
Two
Ví dụ tiếp theo sẽ sử dụng default
trong câu lệnh switch để xác định một đoạn code sẽ được thực thi khi không có case nào khớp với giá trị của biến day
. Trong ví dụ này, biến day
có giá trị là 8 và vì không có case nào khớp với giá trị này, code bên trong khối default sẽ được thực thi.
package main
import "fmt"
func main() {
// Khai báo biến day có giá trị là 8
day := 8
// Sử dụng switch để kiểm tra giá trị của biến day
switch day {
case 1:
fmt.Println("Monday")
case 2:
fmt.Println("Tuesday")
case 3:
fmt.Println("Wednesday")
case 4:
fmt.Println("Thursday")
case 5:
fmt.Println("Friday")
case 6:
fmt.Println("Saturday")
case 7:
fmt.Println("Sunday")
default:
fmt.Println("Not a weekday") // Không phải là ngày trong tuần
}
}
Kết quả của chương trình sẽ là:
Not a weekday
Vì biến day
có giá trị là 8 không khớp với bất kỳ case nào trong switch nên code bên trong khối default sẽ được thực thi và in ra chuỗi “Not a weekday”.
Quy tắc quan trọng của câu lệnh switch trong Go.
Tất cả các giá trị của case phải có cùng kiểu dữ liệu với biểu thức của switch. Trong ví dụ dưới biểu thức switch là biến a
có kiểu là int nhưng giá trị của case thứ hai là chuỗi “b” không có cùng kiểu với int, do đó gây ra lỗi.
package main
import "fmt"
func main() {
// Khai báo biến a có giá trị là 3
a := 3
// Sử dụng switch để kiểm tra giá trị của biến a
switch a {
case 1:
fmt.Println("a is one")
case "b":
fmt.Println("a is b") // Lỗi: Không thể so sánh giá trị chuỗi với kiểu int
}
}
Kết quả của chương trình sẽ là một lỗi:
./prog.go:11:2: cannot use "b" (type untyped string) as type int
Lỗi này xảy ra vì Go yêu cầu tất cả các giá trị trong các case phải có cùng kiểu với biểu thức của switch. Để khắc phục lỗi, bạn cần chắc chắn rằng các giá trị trong các case có cùng kiểu dữ liệu với biểu thức switch của bạn.
2. Cú pháp switch với multi-case switch.
Switch trong Go cũng hỗ trợ việc sử dụng nhiều giá trị cho mỗi case được gọi là Multi-case switch. Điều này có nghĩa là bạn có thể xác định nhiều giá trị cho mỗi case và nếu biểu thức của switch khớp với bất kỳ giá trị nào trong số đó thì code bên trong case đó sẽ được thực thi.
Dưới đây là cú pháp và một ví dụ minh họa:
Cú pháp:
switch expression {
case x, y:
// Thực thi code nếu biểu thức được đánh giá là x hoặc y
case v, w:
// Thực thi code nếu biểu thức được đánh giá là v hoặc w
case z:
// ...
default:
// Thực thi code nếu biểu thức không khớp với bất kỳ case nào
}
Ví dụ:
package main
import "fmt"
func main() {
// Khai báo biến day có giá trị là 5
day := 5
// Sử dụng switch để kiểm tra giá trị của biến day với nhiều giá trị cho mỗi case
switch day {
case 1, 3, 5:
fmt.Println("Odd weekday")
case 2, 4:
fmt.Println("Even weekday")
case 6, 7:
fmt.Println("Weekend")
default:
fmt.Println("Invalid day of day number")
}
}
Kết quả.
Odd weekday
Trong ví dụ này, biến day
có giá trị là 5 vì nó khớp với giá trị trong case 1, 3, 5, code bên trong case đó được thực thi và chương trình in ra “Odd weekday” (Ngày trong tuần là số lẻ).
3. Ví dụ tổng hợp.
Switch cơ bản.
i := 2
fmt.Print("Ghi số ", i, " là ")
switch i {
case 1:
fmt.Println("một")
case 2:
fmt.Println("hai")
case 3:
fmt.Println("ba")
}
Trong ví dụ này, biểu thức i
được so sánh với các giá trị khác nhau và code trong case tương ứng sẽ được thực thi. Trong trường hợp này, vì i
có giá trị là 2, chương trình sẽ in ra “Ghi số 2 là hai.”
Switch với nhiều bểu thức trong một Case.
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("Đây là cuối tuần")
default:
fmt.Println("Đây là ngày trong tuần")
}
Ở đây, switch được sử dụng để kiểm tra ngày hiện tại. Nếu là Thứ Bảy hoặc Chủ Nhật, chương trình sẽ in ra “Đây là cuối tuần,” ngược lại sẽ in ra “Đây là ngày trong tuần.”
Switch không có biểu thức (Thay thế cho if/else):
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Hiện tại là trước trưa")
default:
fmt.Println("Hiện tại là sau trưa")
}
Trong ví dụ này, switch không có biểu thức. Nó kiểm tra giờ hiện tại và nếu là trước 12 giờ trưa, chương trình sẽ in ra “Hiện tại là trước trưa,” ngược lại sẽ in ra “Hiện tại là sau trưa.”
Xác định type switch:
whatAmI := func(i interface{}) {
switch t := i.(type) {
case bool:
fmt.Println("Tôi là một giá trị bool")
case int:
fmt.Println("Tôi là một giá trị int")
default:
fmt.Printf("Không biết kiểu dữ liệu %T\n", t)
}
}
whatAmI(true)
whatAmI(1)
whatAmI("Xin chào")
Đây là một ví dụ về type switch. Nó kiểm tra kiểu dữ liệu của biến i
và thực hiện các hành động tương ứng với kiểu đó. Trong ví dụ này, nó in ra xem i
có phải là kiểu bool, int hay một kiểu dữ liệu không xác định và chương trình sẽ in ra các thông điệp tương ứng.
Tổng hợp lại các ví dụ trên.
package main
import (
"fmt"
"time"
)
func main() {
i := 2
fmt.Print("Write ", i, " as ")
switch i {
case 1:
fmt.Println("one")
case 2:
fmt.Println("two")
case 3:
fmt.Println("three")
}
switch time.Now().Weekday() {
case time.Saturday, time.Sunday:
fmt.Println("It's the weekend")
default:
fmt.Println("It's a weekday")
}
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("It's before noon")
default:
fmt.Println("It's after noon")
}
whatAmI := func(i interface{}) {
switch t := i.(type) {
case bool:
fmt.Println("I'm a bool")
case int:
fmt.Println("I'm an int")
default:
fmt.Printf("Don't know type %T\n", t)
}
}
whatAmI(true)
whatAmI(1)
whatAmI("hey")
}
Bạn có kết quả.
$ go run switch.go
Write 2 as two
It's a weekday
It's after noon
I'm a bool
I'm an int
Don't know type string
4. Khi nào dùng Switch và khi nào dùng if else.
Cả switch
và if-else
là các cấu trúc điều kiện trong ngôn ngữ lập trình Go (Golang) và được sử dụng để thực hiện các quyết định dựa trên giá trị của biểu thức điều kiện. Tuy nhiên, có một số điểm khác nhau giữa chúng và quyết định sử dụng switch
hay if-else
phụ thuộc vào tình huống của bạn và yêu cầu cụ thể của vấn đề.
4.1. Sử dụng switch
khi.
Kiểm tra nhiều giá trị cho một biến.
switch day {
case "Monday":
// do something
case "Tuesday":
// do something else
// ...
default:
// do something if none of the cases match
}
So sánh với các giá trị cụ thể.
switch number {
case 1:
// do something for 1
case 2:
// do something for 2
// ...
default:
// do something if none of the cases match
}
Kiểm tra kiểu dữ liệu.
switch x.(type) {
case int:
// do something if x is int
case string:
// do something if x is string
// ...
default:
// do something if none of the cases match
}
4.2. Sử dụng if-else
khi.
Kiểm tra điều kiện phức tạp hơn.
if x > 10 {
// do something
} else if x > 5 {
// do something else
} else {
// do something if none of the conditions are true
}
Cần kiểm tra một loạt các điều kiện liên tiếp.
if x > 0 && x < 10 {
// do something
} else if x < 0 {
// do something else
} else {
// do something if none of the conditions are true
}
Cần thực hiện một số logic phức tạp mà không thích hợp với cấu trúc switch
.
if condition1 {
// do something
} else if condition2 {
// do something else
// ...
} else {
// do something if none of the conditions are true
}
Lựa chọn giữa switch
và if-else
phụ thuộc vào mức độ phức tạp của điều kiện cần kiểm tra và yêu cầu cụ thể của logic điều kiện trong mã của bạn.