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

Trả về nhiều lần và trả về có tên

Trong Go, một hàm có thể trả về nhiều giá trị. Đó là cơ chế mà kích hoạt mẫu (value, error) bạn đã thấy và nó lan rộng khắp toàn bộ thư viện tiêu chuẩn.

Trả lại nhiều lần

Các kiểu trả về nằm giữa các dấu ngoặc đơn, được phân tách bằng dấu phẩy:

Go
func divmod(a, b int) (int, int) {
    return a / b, a % b
}

q, r := divmod(17, 5) // q=3, r=2

Chúng bị phá hủy với nhiều nhiệm vụ. Để loại bỏ một trong các giá trị sử dụng _:

Go
_, r := divmod(17, 5) // solo il resto

Mẫu (T, error) chuẩn

Hầu như tất cả stdlib đều tuân theo nó. error LUÔN là cuối cùng:

Go
func read(path string) ([]byte, error) {
    data, err := os.ReadFile(path)
    if err != nil {
        return nil, fmt.Errorf("read %q: %w", path, err)
    }
    return data, nil
}

Trả về có tên

Bạn có thể đặt tên cho các giá trị trả về: chúng trở thành các biến được khai báo trước được khởi tạo bằng 0 và return không có đối số sẽ trả về chúng ("trần trụi trở lại"):

Go
func divmod(a, b int) (q, r int) {
    q = a / b
    r = a % b
    return       // naked: ritorna q, r
}

Trả về được đặt tên cũng xuất hiện trong chú giải công cụ tài liệu, vì vậy chúng rất hữu ích dưới dạng tài liệu nội tuyến cho các hàm phức tạp — không chỉ cho sự trở lại trần trụi.

Nhiều hơn hai lần trả lại?

Không có gì ngăn cản bạn (int, int, int, error), nhưng nếu bạn cảm thấy cần thiết hầu như đó luôn là dấu hiệu cho thấy bạn nên trả về một struct:

Go
type Result struct {
    Sum  int
    Avg  float64
    Max  int
}

func analyze(nums []int) (Result, error) { ... }

Hãy thử nó

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

Xác định divmod(a, b int) (int, int) trả về thương số và số dư.

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

Kiểu trả về giữa các dấu ngoặc đơn: `(int, int)`.

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

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

Triển khai safeDiv(a, b int) (int, error): if b == 0 return (0,errors.New('divione per zero')), ngược lại (a/b, nil).

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

Lỗi LUÔN LUÔN là giá trị cuối cùng. Khi có lỗi: giá trị 0 + lỗi.

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

Quiz#go.m3.l2.e3
Sẵn sàng

Chương trình này in gì khi sử dụng kết quả trả về có tên?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
Tùy chọn trả lời

Tóm tắt lại

  • Nhiều giá trị giữa các dấu ngoặc đơn: func f() (T1, T2, error).
  • Quy ước: error LUÔN LUÔN là giá trị cuối cùng; có lỗi, giá trị 0 + lỗi.
  • Trả về được đặt tên khai báo trước các biến và cho phép trả về trần.
  • Trả về trần chỉ trong các chức năng rất ngắn; Ngoài ra, khả năng đọc bị ảnh hưởng.
  • Hơn 2-3 lần trả lại? Bạn có thể muốn một struct.