58

関数の戻りパラメータに名前を付けると、どのような利点がありますか?

func namedReturn(i int) (ret int) {
    ret = i
    i += 2
    return
}

func anonReturn(i int) int {
    ret := i
    i += 2
    return ret
}
4

4 に答える 4

60

それらに名前を付けると、いくつかの利点があります。

  • ドキュメントとして機能します。
  • それらは自動宣言され、ゼロ値に初期化されます。
  • 複数のリターン サイトがある場合、関数の戻り値を変更する場合、単に "return" と表示されるため、すべてを変更する必要はありません。

欠点もあります。主に、同じ名前の変数を宣言することで、誤ってそれらをシャドウするのが簡単です。


効果的な Go には、名前付きの結果パラメーターに関するセクションがあります

Go 関数の戻り値または結果の「パラメーター」には、入力パラメーターと同様に、名前を付けて通常の変数として使用できます。名前が付けられると、関数の開始時にその型のゼロ値に初期化されます。関数が引数なしで return ステートメントを実行する場合、結果パラメーターの現在の値が戻り値として使用されます。

名前は必須ではありませんが、コードを短く明確にすることができます。名前はドキュメントです。nextInt の結果に名前を付けると、返された int がどれであるかが明らかになります。

func nextInt(b []byte, pos int) (value, nextPos int) {

[...]

于 2013-02-26T13:09:39.203 に答える
24

名前付き戻り変数のもう 1 つの特別な用途は、遅延関数リテラルによってキャプチャされることです。些細な例:

package main

import (
    "errors"
    "fmt"
)

func main() {
    fmt.Println(f())
}

var harmlessError = errors.New("you should worry!")

func f() (err error) {
    defer func() {
        if err == harmlessError {
            err = nil
        }
    }()
    return harmlessError
}

出力は<nil>です。より実用的なシナリオでは、遅延関数がパニックを処理し、エラー結果以外の戻り値を変更する場合があります。ただし、共通の魔法は、延期されたリテラルが、 f が終了した後に、通常またはパニックによってf の戻り値を変更する機会があることです。

于 2013-02-26T14:36:41.087 に答える
4

少なくとも 2 つの場合に役立ちます。

  1. 返す変数を宣言する必要があるときはいつでも。例えば

    func someFunc() (int, error) {
        var r int
        var e error
        ok := someOtherFunc(&r)  // contrived, I admit
        if !ok {
            return r, someError()
        }
        return r, nil
    }
    

    対。

    func someFunc() (r int, e error) {
        ok := someOtherFunc(&r)
        if !ok {
            e = someError()
        }
        return
    }
    

    これは、関数を通る実行パスの数が増えるにつれて、より重要になります。

  2. 戻り値を文書化していて、それらを名前で参照したい場合。godoc関数のシグネチャの戻り変数の一部と見なされます。

于 2013-02-26T13:10:27.940 に答える
2

たとえば、名前付きの戻りパラメータには、名前でアクセスできます。

func foo() (a, b, c T) {
        // ...
        if qux {
                b = bar()
        }
        // ...
        return
}

これは、名前付きの戻りパラメーターなしで複製するのは簡単ではありません。名前付き戻りパラメータと本質的に同じ機能のローカル変数を導入する必要があります。

func foo() (T, T, T) {
        var a, b, c T
        // ...
        if qux {
                b = bar()
        }
        // ...
        return a, b, c
}

したがって、それを直接許可する方が簡単です。

さらに、他の方向からもアクセスできます。

func foo() (a, b, c T) {
        // ...
        if a > c {
                b = bar()
        }
        // ...
        return
}

等。

于 2013-02-26T13:20:52.127 に答える