20. 8 важных знаний об импорте пакетов на языке Go

Python

Привет всем, меня зовут Мин.

В период самостоятельного изучения Golang я написал подробные учебные заметки и разместил их в своем личном общедоступном аккаунте WeChat «Время программирования на Go».Что касается языка Go, я тоже новичок, поэтому то, что я написал, должно больше подходить для новых студентов, если вы только изучаете язык Go, вам стоит обратить на него внимание, учиться и расти вместе.

Мой онлайн-блог:golang.iswbm.comМой Github: github.com/iswbm/GolangCodingTime


1. Однострочный импорт и многострочный импорт

В Go пакет может содержать несколько.goфайлы (эти файлы должны находиться на том же уровне папки), если эти.goИспользуется заголовок файлаpackageключевое слово объявляет тот же пакет.

Существует два основных способа импорта пакетов:

  • импорт одной строки
import "fmt"
import "sync" 
  • Многострочный импорт
import(
    "fmt"
    "sync"
)

Как видите, пакет, импортируемый на языке Go, должен быть заключен в двойные кавычки, поэтому я буду жаловаться здесь.

2. Используйте псевдонимы

В некоторых сценариях нам может потребоваться переименовать импортированный пакет, например

  • Возник конфликт, когда мы импортируем два пакета с одинаковым именем пакета, в это время для одного из пакетов определен псевдоним.
import (
    "crypto/rand"
    mrand "math/rand" // 将名称替换为mrand避免冲突
)
  • Мы импортировали пакет с длинным именем, чтобы потом не писать такое длинное имя пакета, мы можем определить такой псевдоним
import hw "helloworldtestmodule"
  • Предотвратите конфликты имен импортированных пакетов с локальными переменными, такими как путь, очень распространенное имя переменной, которое конфликтует с импортированными стандартными пакетами.
import pathpkg "path"

3. Используйте точечные операции

Если мы часто используем набор инструментов в нашей программе, такой как fmt, каждый раз, когда мы используем его функцию печати для печати, нам нужно имя пакета + имя метода.

Для такого типа пакета, который использует высокую частоту, вы можете определить его как "自己人"(с помощью.), собственные слова, независимо друг от друга, его метод - наш метод.

Отныне нам больше не нужно добавлять fmt для печати.

import . "fmt"

func main() {
    Println("hello, world")
}

Однако у такого использования есть определенные скрытые опасности, то есть в импортированном пакете могут быть функции, которые будут конфликтовать с нашими собственными функциями.

4. Инициализация пакета

В каждом пакете разрешено иметь одинinitфункция, когда этот пакет импортируется, выполнит этот пакетinitдля выполнения некоторых задач инициализации.

заinitЕсть две вещи, на которые следует обратить внимание при выполнении функции.

  1. initфункция имеет приоритет надmainвыполнение функции

  2. В цепочке ссылок пакетов инициализация пакета идет в глубину. Например, если существует такое отношение ссылки на пакет: main→A→B→C, то последовательность инициализации следующая:

    C.init→B.init→A.init→main

5. Анонимный импорт пакетов

Когда мы импортируем пакет, если пакет не используется, во время компиляции будет сообщено об ошибке.

Но в некоторых случаях мы импортируем пакет и просто хотим его выполнить.initдля запуска некоторых задач инициализации, что мне делать в это время?

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

// 注册一个PNG decoder
import _ "image/png"

Поскольку функция инициализации выполняется при импорте, пакет все равно будет скомпилирован в исполняемый файл при компиляции.

6. Импортируются ли пути или пакеты?

Когда мы импортируем с помощью импортаtestmodule/fooКогда, новички, часто спрашивают, этоfooЭто пакет или просто имя каталога, в котором находится пакет?

import "testmodule/foo"

Чтобы прийти к такому выводу, был проведен специальный эксперимент (см. «Пример кода в пункте 7»), и окончательный вывод был следующим:

  • При импорте импортируется по справочнику. После импорта каталога можно использовать все пакеты в этом каталоге.
  • По привычке имя пакета и имя каталога обычно устанавливаются одинаковыми, поэтому у вас создается иллюзия, что вы импортируете пакет.

7. Относительный и абсолютный импорт

Насколько я знаю, до Go 1.10 вроде относительный импорт не поддерживался, и только после Go 1.10.

абсолютный смысл:от$GOPATH/srcили$GOROOTили$GOPATH/pkg/modПоиск пакетов в каталоге и импорт

относительный импорт: Поиск пакетов из текущего каталога и начало импорта. как ниже

import (
    "./module1"
    "../module2"
    "../../module3"
    "../module4/module5"
)

Возьмем пример

1. Используйте абсолютный импорт

Существует следующая структура каталогов (убедитесь, что текущий каталог находится в GOPATH)

где main.go такой

package main

import (
    "app/utilset"   // 这种使用的就是绝对路径导入
)

func main() {
    utils.PrintHello()
}

И в том же каталоге main.go есть еще одна папкаutilset, чтобы вы поняли"Шестой пункт: import импортирует пути вместо пакетов», я определилhello.goфайл, этот файл go определяет пакет, к которому он принадлежитutils.

package utils

import "fmt"

func PrintHello(){
    fmt.Println("Hello, 我在 utilset 目录下的 utils 包里")
}

Текущий результат выглядит следующим образом

2. Используйте относительный импорт

Или приведенный выше код после изменения абсолютного импорта на относительный импорт

Установите путь GOPATH обратно (сравните GOPATH с абсолютным путем выше)

затем бегите снова

Подводя итог, используя относительный импорт, следует отметить два момента.

  • товар не ставить$GOPATH/src, иначе будет сообщено об ошибке (например, после того, как я изменю текущий каталог проекта на GOPATH, операция сообщит об ошибке)

  • Модули Go не поддерживают относительный импорт. После включения GO111MODULE относительный импорт использовать нельзя.

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

Поэтому обычно рекомендуется использовать абсолютные ссылки. Если вы используете абсолютные ссылки, вам придется снова говорить о приоритете.

8. Приоритет пути импорта пакетов

В предыдущем разделе были представлены три различные схемы управления зависимостями пакетов.В разных режимах управления могут быть разные пути для хранения пакетов.Некоторые пакеты могут быть помещены в GOPATH, некоторые могут быть помещены в поставщика, а другие могут быть помещены в поставщика.Некоторые пакеты встроенные пакеты, размещенные в GOROOT.

Тогда возникает вопрос: если есть пакет с тем же именем пакета, но с другой версией по этим трем разным путям, какой из них мы выбираем для импорта при импорте?

Это требует от нас понимания, каков приоритет пути поиска пакетов в Golang?

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

При использовании говендора

Когда мы импортируем пакет, он будет:

  1. Сначала из корневого каталога проектаvendorнайти в каталоге
  2. Наконец от$GOROOT/srcНайдите в каталоге
  3. затем из$GOPATH/srcНайдите в каталоге
  4. Если вы не можете найти его, будет сообщено об ошибке.

Для того, чтобы проверить этот процесс, после того, как в создании я создал директорию поставщика, я включил режим поставщика.Я случайным образом импортировал пакет pkg в main.go.Так как этот пакет был произвольно указан мной, я, конечно, не мог найти его. Если нет, будет сообщено об ошибке. Golang напечатает процесс поиска в сообщении об ошибке. Из этой информации вы можете увидеть приоритет поиска пакета Golang.

При использовании модулей go

Если пакет, который вы импортируете, имеет доменное имя, он будет$GOPATH/pkg/modПоиск ниже, если вы не можете найти его, перейдите на веб-сайт, чтобы найти его.Если вы не можете найти его или обнаружите, что это не пакет, будет сообщено об ошибке.

И если пакет, который вы импортируете, не имеет доменного имени (например, «fmt»), он будет отправлен только на$GOROOTНайти в.

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

как правилоvendorкаталог черезgo mod vendorСгенерированная командой, эта команда упакует все зависимости проекта в папку verdor в каталоге вашего проекта.

дальнейшее чтение

Руководство по серии

01. Построение среды разработки (Goland & VS Code)

02. Изучите пять методов создания переменных

03. Подробные типы данных:**Целое число и число с плавающей запятой**

04. Подробные типы данных: байт, руна и строка

05. Подробно объясните типы данных: массивы и срезы

06. Подробно объясните типы данных: словари и логические значения

07. Подробно объясните типы данных: указатели

08. Объектно-ориентированное программирование: структуры и наследование

09. Статья для понимания функций в Go

10. Управление потоком языка Go: условный оператор if-else

11. Управление потоком языка Go: оператор выбора switch-case

12. Управление потоком языка Go: оператор цикла for

13. Перейти к управлению языковым потоком: перейти к безусловному переходу

14. Перейти к управлению языковым потоком: отложить отложенный вызов

15. Объектно-ориентированное программирование: интерфейсы и полиморфизм

16. Ключевые слова: В чем разница между make и new?

17. Статья о понимании блоков и области видимости в Go

18. Изучите Go Coroutines: горутины

19. Изучите сопрограммы Go: подробно объясните каналы/каналы

20. Подробное объяснение нескольких классических случаев зависания канала.

21. Изучите сопрограммы Go: группа ожидания

22. Изучите процедуры Go: мьютексы и блокировки чтения-записи

23. Обработка исключений в Go: паника и восстановление

24. Сверхдетальная интерпретация прошлой жизни Go Modules и вводное использование

25. 8 важных знаний об импорте пакетов на языке Go

26. Как открыть исходный код модулей, которые я написал для использования другими?

27. Расскажите об утверждениях типов в Go?

28. Эти пять пунктов помогут вам понять, как использовать select в языке Go.