Должно ли имя пакета в Go совпадать с именем самого внутреннего каталога?

ВНИМАНИЕ, этот вопрос касается спецификаций языка Go, а не рекомендаций или рекомендаций.

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

Моя структура проекта похожа на следующие снимки экрана. Когда я делаю go run ~/go/src/myproj/main.go, ошибка говорит:

src \ myproj \ main.go: 5: 2: не удается найти пакет myproj / pa / pb ни в одном из: c: \ go \ src \ myproj \ pa \ pb (из $ GOROOT) C: \ Users \ terry \ go \ src \ myproj \ pa \ pb (из $ GOPATH)

введите описание изображения здесь

введите описание изображения здесь

Однако, если я изменю package pb на package pa в p.go, и изменю импорт с "myproj/pa/pb" на "myproj/pa", и изменю fmt.Print(pb.Greet) на fmt.Print(pa.Greet) в main.go, это сработает. Должен ли самый внутренний каталог соответствовать имени объявления пакета? Моя версия для игры — 1.14.4

Должен ли самый внутренний каталог соответствовать имени объявления пакета? Нет, конечно нет. Но это очень разумное соглашение, и вы никогда не должны его нарушать, потому что люди будут ненавидеть вас (справедливо), если вы это сделаете.   —  person Peiti Li    schedule 30.06.2020

См. также:  Тупик в диапазоне по каналу в конвейере с несколькими группами ожидания
Понравилась статья? Поделиться с друзьями:
IT Шеф
Комментарии: 3
  1. Peiti Li

    В go принято соглашение, что имя пакета должно совпадать с именем его исходного каталога.

    Вот, например, выдержка из Effective Go Blog:

    Другое соглашение состоит в том, что имя пакета является базовым именем его исходного каталога; пакет в src / encoding / base64 импортируется как encoding / base64, но имеет имя base64, а не encoding_base64 и encodingBase64.

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

  2. Peiti Li

    После некоторых проб и ошибок я выяснил, что произошло. Имя пакета должно совпадать с именем самого внутреннего каталога? Нет.

    В main.go просто сделайте следующее, он должен работать.

    package main
    
    import (
        "fmt"
        "myproj/pa"
    )
    
    func main() {
        fmt.Print(pb.Greet)
    }
    

    Также мы можем дать ему псевдоним, например, следующий тоже работает.

    package main
    
    import (
        "fmt"
        pc "myproj/pa"
    )
    
    func main() {
        fmt.Print(pc.Greet)
    }
    

    Это означает, что пакет в go — это каталог файлов с объявлением package xxx. Имя каталога имеет значение во время импорта. Каталог является частью пути для импорта. Но в импортированном файле используется xxx в package xxx или псевдоним для этого xxx.

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

    Технически это возможно … Но никогда не стоит этого делать. person Peiti Li; 30.06.2020

    этот вопрос задает спецификации Go, а не рекомендации или лучшие практики. Приведя приведенный выше пример, люди поймут, как работает пакет go, и больше не запутаются, когда увидят, что в каком-то третьем пакете есть такие вещи. person Peiti Li; 30.06.2020

    Я знаю, что вы хотите сказать, и ценю, что вы хотите узнать технические подробности. Я пытаюсь сказать, что ни разу за те 5 лет, которые я сейчас работаю с Go, я не видел, чтобы имена пакетов отличались от их исходного каталога. person Peiti Li; 01.07.2020

  3. Peiti Li

    В Go должно ли имя пакета совпадать с именем самого внутреннего каталога?

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

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

    package <package_name> // import "<import_path>"
    

    Это полезно: ваша файловая структура не способствует описательному имени, например, при использовании нескольких версий в пути к файлу.

    Например, клиентский SDK Google использует следующие пути:

    • Имя пакета: slides
    • Путь импорта: google.golang.org/api/slides/v1

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

    package slides // import "google.golang.org/api/slides/v1"
    

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

    package main
    
    import(
        "google.golang.org/api/slides/v1"
    )
    
    func main() {
        fmt.Println(slides.PresentationsScope)
    }
    

    Подробнее см. Здесь: https://github.com/googleapis/google-api-go-client/blob/master/slides/v1/slides-gen.go

    В приведенном здесь примере вы должны использовать:

    package pb // import "myproj/pa"
    

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

    import pb "myprog/pa"
    
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: