📕
Golang
  • Собеседование по golang
  • Вопросы собеседования
    • Список вопросов МТС
    • Список вопросов
    • Базовые вопросы по Golang
    • Go. Прорабатываем 25 основных вопросов собеседования
    • Функции
    • Структуры данных
    • Конкурентность и Параллелизм
    • Горутины
    • Примитивы синхронизации
    • Планировщик
    • Go: конкурентность и привязки к потокам в планировщике
    • Каналы
    • GC
  • спецификация
    • Спецификация Go: преобразования в и из строкового типа
    • переключатель типов (type switch)
    • for утверждения (for statements)
    • for утверждения с range условием
    • go утверждения (go statements)
    • select утверждения (select statements)
    • return утверждения (return statements)
    • continue утверждения (continue statements)
    • goto утверждения (goto statements)
    • fallthrough утверждения (fallthrough statements, утверждения "провала")
    • defer утверждения (defer statements)
    • встроенные функции, функция close
    • длина и емкость
    • аллокация, создание срезов (slice), карт (map) и каналов
    • добавление в срезы и копирование срезов
    • удаление элементов карты
    • обработка паники
    • начальная загрузка (bootstrapping)
    • пакеты
    • инициализация и выполнение программы, нулевое значение
    • инициализация пакета
    • выполнение программы
    • ошибки
    • паника во время выполнения (run-time panic)
  • Эффективный go
    • эффективный go
    • 50 оттенков go
    • Go: распространенные антипаттерны
    • Визуализация concurrency в Go с WebGL
  • требования для работы
    • Список навыков
  • habr
    • Изучаем многопоточное программирование в Go по картинкам
    • Go: конкурентность и привязки к потокам в планировщике
  • NP
    • Полиморфизм с интерфейсами в Golang
    • Объектно-ориентированное программирование в Golang
    • Владеешь merge  -  освой и rebase
  • ProgLib
    • Горутины
  • Untitled
  • Оптимизация
    • Go: Должен ли я использовать указатель вместо копии моей структуры?
  • Полезняшки
    • Using PostgreSQL JSONB with Go
Powered by GitBook
On this page

Was this helpful?

  1. спецификация

пакеты

Go программы создаются путем объединения пакетов. Пакет в свою очередь состоит из одного или нескольких исходных файлов, которые вместе объявляют константы, типы, переменные и функции, принадлежащие пакету, и которые доступны во всех файлах одного и того же пакета. Эти элементы могут быть экспортированы и использованы в другом пакете.

Организация исходного файла

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

SourceFile = PackageClause ";" { ImportDecl ";" } { TopLevelDecl ";" } .

Пункт package

Пункт package начинает каждый исходный файл и определяет пакет, к которому принадлежит файл.

PackageClause  = "package" PackageName .
PackageName    = identifier .

PackageName не должно быть пустым идентификатором. Пример:

package math

Набор файлов с одинаковым PackageName формирует реализацию пакета. Реализация может потребовать, чтобы все исходные файлы пакета находились в одном каталоге.

Import объявления

В объявлении импорта указывается, что исходный файл, содержащий объявление, зависит от функциональности импортированного пакета (инициализация и выполнение программы) и обеспечивает доступ к экспортированным идентификаторам этого пакета. При импорте указывается идентификатор (PackageName), который будет использоваться для доступа, и ImportPath, который указывает импортируемый пакет.

ImportDecl = "import" ( ImportSpec | "(" { ImportSpec ";" } ")" ) .
ImportSpec = [ "." | PackageName ] ImportPath .
ImportPath = string_lit .

PackageName используется в квалифицированных идентификаторах для доступа к экспортированным идентификаторам пакета в исходном импортирующем файле. Это объявлено в блоке файла. Если PackageName опущено, по умолчанию используется идентификатор, указанный в предложении пакета импортируемого пакета. Если вместо имени появляется явный период (.), все экспортированные идентификаторы пакета, объявленные в блоке пакета этого пакета, будут объявлены в блоке файла импортирующего исходного файла и должны быть доступны без квалификатора.

Интерпретация ImportPath зависит от реализации, но обычно является подстрокой полного имени файла скомпилированного пакета и может относиться к хранилищу установленных пакетов.

Ограничение реализации: компилятор может ограничивать ImportPaths непустыми строками, используя только символы, принадлежащие общим категориям Unicode L, M, N, P и S (графические символы без пробелов), а также может исключать символы !"#$%&'()*,:;<=>?[\]^`{|} и символ замены Unicode U+FFFD.

Предположим, что мы скомпилировали пакет, содержащий выражение пакета package math, которое экспортирует функцию Sin, и установили скомпилированный пакет в файл, обозначенный как «lib/math». В следующей таблице показано, как обращаться к Sin в файлах, которые импортируют пакет после различных типов объявлений импорта.

Import declaration          локальное имя Sin

import   "lib/math"         math.Sin
import m "lib/math"         m.Sin
import . "lib/math"         Sin

Декларация импорта объявляет отношение зависимости между импортирующим и импортированным пакетом. Запрещается импортировать сам пакет, прямо или косвенно, или напрямую импортировать пакет без ссылки на какие-либо экспортируемые идентификаторы. Чтобы импортировать пакет исключительно для его побочных эффектов (инициализация), используйте пустой идентификатор в качестве явного имени пакета:

import _ "lib/math"

Пример пакета

Вот полный Go пакет, который реализует конкуррентный отсеиватель простых чисел.

package main

import "fmt"

// Отправляем последовательность 2, 3, 4, … в канал 'ch'.
func generate(ch chan<- int) {
  for i := 2; ; i++ {
    ch <- i  // Отправляем 'i' в канал 'ch'.
  }
}

// Копируем значения из канала 'src' в канал 'dst',
// удаляем те что делимы на 'prime'.
func filter(src <-chan int, dst chan<- int, prime int) {
  for i := range src {  // Проходим в цикле по значениям 
                        // полученным из 'src'.
    if i%prime != 0 {
      dst <- i  // Отправляем 'i' в канал 'dst'.
    }
  }
}

// Отсеиватель простых чисел: 
// Гирляндный фильтр работает вместе.
func sieve() {
  ch := make(chan int)  // Создаем новый канал.
  go generate(ch)       // Запускаем generate() 
                        // как подпроцесс.
  for {
    prime := <-ch
    fmt.Print(prime, "\n")
    ch1 := make(chan int)
    go filter(ch, ch1, prime)
    ch = ch1
  }
}

func main() {
  sieve()
}
Previousначальная загрузка (bootstrapping)Nextинициализация и выполнение программы, нулевое значение

Last updated 4 years ago

Was this helpful?