Chuyển đến nội dung chính
Mô-đun 6 · Bài học 3 trong tổng số 528/50 trong khóa học~10 min
Bài học theo mô-đun (3/5)

Công tắc loại

Công tắc loại phân biệt giữa nhiều loại có thể có của một giá trị giao diện. Đó là sự khái quát hóa của comma ok khi có nhiều hơn một trường hợp.

Cú pháp

Go
func describe(i interface{}) string {
    switch v := i.(type) {
    case int:
        return fmt.Sprintf("int %d", v)
    case string:
        return fmt.Sprintf("string %q", v)
    case nil:
        return "nil"
    default:
        return fmt.Sprintf("altro tipo: %T", v)
    }
}
  • i.(type) là cú pháp đặc biệt, CHỈ hợp lệ bên trong switch.
  • v := ... liên kết giá trị với loại của trường hợp hiện tại: bên trong case int, v có loại int.
  • default bắt được tất cả các loại khác; ở đó v có loại giao diện gốc.
  • case nil khớp giao diện với loại động không.

Vụ án “không tên”

Nếu không cần giá trị đã nhập, bạn có thể bỏ qua v:

Go
switch i.(type) {
case int:
    // you know it's an int, but you don't have a variable of that type
case string:
    // ...
}

Là biểu mẫu dùng khi bạn chỉ cần phân biệt loại chứ không cần thao tác về giá trị.

Nhiều loại trong cùng một trường hợp

Go
switch v := i.(type) {
case int, int64:
    // here v is still interface{}: the "common" type is just the interface
    fmt.Println("numero intero:", v)
case string:
    // here v is string
    fmt.Println("stringa:", v)
}

Trường hợp sử dụng điển hình: in có định dạng

Go
func print(i interface{}) {
    switch v := i.(type) {
    case int:
        fmt.Printf("%d\n", v)
    case string:
        fmt.Printf("%s\n", v)
    case fmt.Stringer:
        fmt.Println(v.String())
    default:
        fmt.Printf("%v\n", v)
    }
}

Bản thân fmt.Println sử dụng công tắc loại bên trong để xử lý các định dạng chuẩn.

Loại chuyển đổi so với phản ánh

Đối với một số loại đã biết → chuyển đổi loại (nhanh, dễ đọc). Để kiểm tra động các loại không xác định → gói reflect (thêm mạnh mẽ nhưng chậm hơn và dài dòng hơn).

Hãy thử nó

tập thể dục#go.m6.l3.e1
Nỗ lực: 0Đang tải…

Triển khai chuỗi mô tả (i giao diện{}) trả về 'int', 'chuỗi' hoặc 'altro' tùy thuộc vào loại động.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Cú pháp: `switch i.(type) { case T: ... default: ... }`.

Giải pháp khả dụng sau 3 lần thử

tập thể dục#go.m6.l3.e2
Nỗ lực: 0Đang tải…

Viết printVal(i giao diện{}) sử dụng v := i.(type) và in bằng %d cho int, %s cho chuỗi.

Đang tải trình chỉnh sửa…
Hiển thị gợi ý

Bên trong `case int`, v có kiểu int (bạn có thể chuyển nó sang Printf).

Giải pháp khả dụng sau 3 lần thử

Quiz#go.m6.l3.e3
Sẵn sàng

Cú pháp nào bắt đầu chuyển đổi loại?

Go
switch ??? {
  case int: ...
}
Tùy chọn trả lời

Tóm tắt lại

  • switch v := i.(type) { case T: ... }: phân biệt loại động.
  • Bên trong hộp đựng một loại, v có loại hộp đựng.
  • case T1, T2: v giữ nguyên kiểu giao diện ban đầu.
  • default đối với các trường hợp chưa được xử lý; case nil cho giao diện không.
  • Không có fallthrough trong loại công tắc.
  • 1 kiểu → khẳng định kiểu; Hơn 2 loại → chuyển đổi loại.