Переменная не используется при использовании именованного типа возвращаемого значения - PullRequest
0 голосов
/ 09 апреля 2019

Почему я могу сделать следующее для определения итератора в Go:

func f() func() int {
    i := 1
    return func() int {
        i++
        return i
    }
}

но это приведет к ошибке неиспользованной переменной (i не используется)?

func f() func() int {
    i := 1
    return func() (i int) {
        i++
        return
    }
}

Основная функция:

func main() {
    iter := f()
    fmt.Println(iter())
    fmt.Println(iter())
    fmt.Println(iter())
    fmt.Println(iter())
}

Для меня обе версии делают одно и то же: они используют f в качестве итератора. f использует замыкания (более конкретно i). Первая версия явно возвращает увеличенный i, а вторая неявно, ссылаясь на нее через именованный тип возвращаемого значения.

Для меня обе версии одинаковы, так почему я получаю сообщение об ошибке?

1 Ответ

5 голосов
/ 09 апреля 2019

Во втором случае возвращаемое значение (i int) скрывает внешнюю декларацию i := 1. Так что это первый i, который не используется. Это означает, что второй пример совсем не является закрытием.

С точки зрения области видимости, ваш второй пример такой же, как:

func f() func() int {
    i := 1
    return func(i int) int {
        i++
        return
    }
}

В этом случае должно быть ясно, что внутренний i различен и затеняет внешний.

...