メインコンテンツにスキップ
モジュール 3 · レッスン 2 / 5コース内の 12/50~12 min
モジュールのレッスン (2/5)

複数の戻り値と名前付き戻り値

Go では、関数は 複数の値を返すことができます。という仕組みなのですが、 すでに見られ、浸透している (value, error) パターンを有効にします 標準ライブラリ全体。

複数の返品

戻り値の型は括弧内にカンマで区切って指定します。

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

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

それらは複数の代入により構造化されません。いずれかを破棄するには、 値には _ を使用します。

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

正規の (T, error) パターン

ほぼすべての stdlib がこれに従います。 error は常に最後です。

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
}

名前付きリターン

戻り値に名前を付けることができます。戻り値は事前に宣言された変数になります。 ゼロに初期化され、引数なしの return はそれらを返します (「裸 戻る"):

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

名前付きリターンはドキュメントのツールチップにも表示されるため、便利です 単なる機能ではなく、複雑な関数の インライン ドキュメントの形式として 裸で返すために。

返品が 2 回以上ありますか?

(int, int, int, error) を妨げるものは何もありませんが、必要に応じて ほとんどの場合、これは struct を返す必要があるという兆候です。

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

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

試してみてください

運動#go.m3.l2.e1
試行回数: 0読み込み中…

商と余りを返す divmod(a, b int) (int, int) を定義します。

エディターを読み込み中…
ヒントを表示

かっこ内の戻り値の型: `(int, int)`。

3 回の試行後に解決策が利用可能になります

運動#go.m3.l2.e2
試行回数: 0読み込み中…

safeDiv(a, b int) (int, error) を実装します。 b == 0 の場合は (0,errors.New('divisione per zero')) を返し、それ以外の場合は (a/b, nil) を返します。

エディターを読み込み中…
ヒントを表示

最後の値として常にエラーが発生します。エラー時: ゼロ値 + エラー。

3 回の試行後に解決策が利用可能になります

Quiz#go.m3.l2.e3
準備完了

このプログラムは名前付き戻り値を使用して何を出力しますか?

Go
func f() (a, b int) {
    a = 1
    b = 2
    return
}
x, y := f()
fmt.Println(x, y)
回答の選択肢

要約

  • 括弧内の複数の値: func f() (T1, T2, error)。
  • 規則: error は常に最後の値として使用されます。エラーの場合、ゼロ値 + エラー。
  • 名前付き戻り値は変数を事前に宣言し、裸の戻り値を有効にします。
  • 非常に短い関数でのみ Naked が返されます。それを超えると、可読性が低下します。
  • 返品は 2 ~ 3 件以上ですか?おそらく構造体が必要でしょう。