Подтвердить что ты не робот

Зачем нужно указывать возвращаемые параметры?

Какие преимущества возникают при названии параметра (-ов) возврата функции?

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

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

Ответ 1

Есть несколько преимуществ для их обозначения:

  • Он служит документацией.
  • Они автоматически объявляются и инициализируются нулевыми значениями.
  • Если у вас несколько сайтов возврата, вам не нужно их менять, если вы измените возвращаемые значения функции, так как просто скажете "return".

Есть и недостатки, в основном, что их легко случайно замаскировать, объявив переменную с тем же именем.

Эффективный Go имеет раздел по названным параметрам результата.

Ответ 2

Другое специальное использование для именованной возвращаемой переменной должно быть записано литералом отложенной функции. Тривиальная иллюстрация:

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 завершается, как обычно, так и паникой.

Ответ 3

Он полезен, по крайней мере, в двух случаях:

  • Всякий раз, когда вам приходится объявлять переменные, которые вы собираетесь вернуть. Например.

    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
    }
    

    Это становится более важным, так как количество путей выполнения через функцию увеличивается.

  • Когда вы документируете возвращаемые значения и хотите ссылаться на них по имени. godoc рассматривает часть возвращаемых переменных в сигнатуре функции.

Ответ 4

Например, имена возвращаемых параметров доступны, ну, имя.

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
}

Etc.