Можно ли из внешней области видимости функции получить доступ к переменной, объявленной во вложенном блоке (scope)?

Ответ

Нет, нельзя. В Go, как и во многих других языках, используется лексическая область видимости (lexical scoping). Это означает, что доступность переменной определяется ее положением в исходном коде.

Ключевые правила:

  1. Все переменные внутри функции являются локальными. Понятие "публичных переменных внутри функции" некорректно. Публичными (экспортируемыми) могут быть только идентификаторы на уровне пакета (переменные, константы, типы, функции), если их имя начинается с заглавной буквы.
  2. Внутренние блоки видят внешние, но не наоборот. Код во вложенном блоке (например, внутри {...}, if, for) может получить доступ к переменным, объявленным во внешних по отношению к нему блоках. Однако код во внешнем блоке не может видеть переменные, объявленные во внутреннем.

Пример:

package main

import "fmt"

func scopeExample() {
    // Внешний блок (уровень функции)
    outerVar := "Я видна везде внутри функции"

    {
        // Внутренний, вложенный блок
        innerVar := "Я видна только здесь, внутри этих скобок"
        fmt.Println(outerVar) // OK: Внутренний блок видит переменную из внешнего
        fmt.Println(innerVar) // OK: Переменная используется в своей области видимости
    }

    fmt.Println(outerVar) // OK: Переменная используется в своей области видимости
    // fmt.Println(innerVar) // Ошибка компиляции: undefined: innerVar
}

Это правило распространяется на все типы блоков, включая условные операторы и циклы:

if x := 10; x > 5 { // Переменная 'x' видна только внутри блока 'if' и 'else'
    fmt.Println(x) // OK
} else {
    fmt.Println(x) // OK
}
// fmt.Println(x) // Ошибка компиляции: undefined: x