Przejdź do głównej treści
eLearner.app
Moduł 3 · Lekcja 2 z 512/50 w kursie~12 min
Lekcje modułu (2/5)

Wielokrotne zwracane wartości i nazwane zwracane wartości

W Go funkcja może zwracać wiele wartości. To jest mechanizm włącza wzorzec (value, error), który już widziałeś i który przenika całą bibliotekę standardową.

Wiele zwrotów

Typy zwracane są umieszczane w nawiasach, oddzielane przecinkami:

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

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

Ulegają zniszczeniu przy wielokrotnym przypisaniu. Aby odrzucić jeden z wartości używają _:

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

Kanoniczny wzorzec (T, error)

Prawie cała biblioteka stdlib jest z nim zgodna. error jest ZAWSZE ostatni:

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
}

Nazwane zwroty

Zwracane wartości można nazwać: stają się one wstępnie zadeklarowanymi zmiennymi zainicjowany na zero, a return bez argumentów zwraca je („naked powrót"):

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

Nazwane zwroty pojawiają się również w etykietkach narzędzi dokumentacji, więc są przydatne jako forma dokumentacji wbudowanej dla złożonych funkcji — i nie tylko za nagi powrót.

Więcej niż dwa powroty?

Nic nie stoi na przeszkodzie, aby skorzystać z (int, int, int, error), ale jeśli czujesz taką potrzebę prawie zawsze jest to znak, że powinieneś zwrócić strukturę:

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

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

Spróbuj

Ćwiczenie#go.m3.l2.e1
Próby: 0Ładowanie...

Zdefiniuj divmod(a, b int) (int, int), który zwraca iloraz i resztę.

Ładowanie edytora...
Pokaż wskazówkę

Zwracane typy w nawiasach: `(int, int)`.

Rozwiązanie dostępne po 3 próbach

Ćwiczenie#go.m3.l2.e2
Próby: 0Ładowanie...

Zaimplementuj SafeDiv(a, b int) (int, błąd): if b == 0 return (0, error.New('dzielenie przez zero')), w przeciwnym razie (a/b, nil).

Ładowanie edytora...
Pokaż wskazówkę

Błąd ZAWSZE jako ostatnia wartość. W przypadku błędu: wartość zerowa + błąd.

Rozwiązanie dostępne po 3 próbach

Quiz#go.m3.l2.e3
Gotowe

Co wypisuje ten program, korzystając z nazwanych zwrotów?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
Opcje odpowiedzi

Podsumowanie

  • Wiele wartości w nawiasach: func f() (T1, T2, error).
  • Konwencja: error ZAWSZE jako ostatnia wartość; w przypadku błędu wartość zerowa + błąd.
  • Nazwane zwroty wstępnie deklarują zmienne i umożliwiają nagie zwroty.
  • Nagie zwroty tylko w bardzo krótkich funkcjach; poza tym cierpi na tym czytelność.
  • Więcej niż 2-3 powroty? Prawdopodobnie chcesz strukturę.