Yerel paketler hareket halindeyken nasıl içe aktarılır?


102

Yerelleştirmek istediğim bir örnek kod üzerinde yeni çalışmaya başladım.

Orijinal main.goithalat bildiriminde şunlardı:

 import (
    "log"
    "net/http"
    "github.com/foo/bar/myapp/common"
    "github.com/foo/bar/myapp/routers"
)

Şimdi sahibim commonve routerspaketim var/home/me/go/src/myapp

Bu yüzden import ifadesini şuna çevirdim:

import (
    "log"
    "net/http"
    "./common"
    "./routers"
)

Ancak çalıştırdığımda go install myappşu hataları alıyorum:

can't load package: /home/me/go/src/myapp/main.go:7:3: local import "./common" in non-local package

Ayrıca, ben kullandığınızda commonve routersyerine ./commonve ./routersithalat açıklamada, alıyorum:

myapp/main.go:7:3: cannot find package "common" in any of:
    /usr/local/go/src/common (from $GOROOT)
    /home/me/go/src/common (from $GOPATH)
myapp/main.go:8:2: cannot find package "routers" in any of:
    /usr/local/go/src/routers (from $GOROOT)
    /home/me/go/src/routers (from $GOPATH)

Bunu nasıl düzeltebilirim?


5
İçe aktarma yoluna bakılmaksızın tüm içe aktarmalar "yerel" dir. Ayrıntılı açıklama için "Go Kodu Nasıl Yazılır " bölümüne bakın .
JimB

24
@JimB felsefi tartışmaları bir kenara bırakırsak, yukarıda bahsettiğim sorunun nasıl çözüleceğini merak ediyorum.
Karlom

3
Felsefi bir açıklama yapmaya çalışmıyorum, kelimenin tam anlamıyla tüm içe aktarmaların yerel dosya sisteminizde olduğunu söylüyorum ; Uzak bir repodan kaynaklanıp kaynaklanmamaları hiçbir zaman fark etmez. Göreceli yolları kullanmaya çalışmayın (bazen işe yararlar, ancak önerilmezler) ve "Go Code Nasıl Yazılır" belgesini, özellikle de "Kod Organizasyonu" bölümünü gözden geçirin .
JimB

Yanıtlar:


70

Ben sorunu çözdüm. Temel olarak içe aktarma için Git başlangıç ​​yolu$HOME/go/src

Bu yüzden myapppaket adlarının önüne eklemem gerekiyor , yani içe aktarma şöyle olmalı:

import (
    "log"
    "net/http"
    "myapp/common"
    "myapp/routers"
)

4
proje adını gibi kullanmak myappkötü bir fikirdir, örneğin proje adını değiştirirseniz, tüm içe aktarma başarısız olur
TomSawyer

9
Alternatif nedir? Go, göreli içe aktarmalar kullanmanızı tavsiye etmez.
Sam Holmes

12
Elbette proje adını değiştirirseniz tüm içe aktarmalar başarısız olacaktır. Proje adı nadiren değişir.
Damien Roche

24
Peki, go1.11 itibariyle yeni modüller sistemini kullanabilirsiniz. go mod init <module_name>ve sonra sadece import "<module_name>/<pkg_name>".
çığlık

.Go dosyamıza github.com/dgrijalva/jwt-go'yu nasıl içe aktarabiliriz? Jwt-go klasörüm içinde src / github.com / dgrijalva
Manik Thakur

34

Yukarıdaki Go 1.5 kullanıyorsanız, satıcı özelliğini kullanmayı deneyebilirsiniz . Yerel paketinizi satıcı klasörünün altına koymanıza ve daha kısa yoldan içe aktarmanıza olanak tanır . Sizin durumunuzda, ortak ve yönlendiriciler klasörünüzü satıcı klasörünün içine koyabilirsiniz, böylece

myapp/
--vendor/
----common/
----routers/
------middleware/
--main.go

ve böyle içe aktar

import (
    "common"
    "routers"
    "routers/middleware"
)

Bu işe yarayacaktır çünkü Go paketinizi $ GOPATH / src yerine projenizin satıcı dizininden başlayarak (en az bir .go dosyası varsa) aramaya çalışacaktır.

Bilginize: Satıcıyla daha fazlasını yapabilirsiniz, çünkü bu özellik bir paket için "tüm bağımlılığınızın kodunu" kendi projenizin dizinine koymanıza izin verir, böylece tüm yapılar için her zaman aynı bağımlılık sürümlerini alabilecektir. Python'da npm veya pip gibidir, ancak bağımlılıklarınızı projenize manuel olarak kopyalamanız gerekir veya bunu kolaylaştırmak istiyorsanız, Daniel Theophanes tarafından govendor'a bakmaya çalışın.

Bu özellik hakkında daha fazla bilgi edinmek için buraya bakmayı deneyin

Satıcı Klasörünü Anlama ve Kullanma, Daniel Theophanes

Lucas Fernandes da Costa'dan Go Bağımlılık Yönetimini Anlamak

Umarım sen veya bir başkası yararlı bulur


19

İçe aktarma yolları, sizin $GOPATHve $GOROOTortam değişkenlerinizle ilişkilidir . Örneğin, aşağıdakilerle $GOPATH:

GOPATH=/home/me/go

İçinde bulunan /home/me/go/src/lib/commonve /home/me/go/src/lib/routerssırasıyla şu şekilde ithal edilen paketler :

import (
    "lib/common"
    "lib/routers"
)

Evet, ilk örnek benim hatamdı.
wlredeye

Takımlama tarafından desteklenmeyen göreli yol derken neyi kastediyorsunuz?
wlredeye

2
go installGöreli içe aktarmalar kullanan paketleri kullanamazsınız .
JimB

Sanırım burada yanlış anlaşılıyor. GOPATH ile ilgili demek istiyorum. "../../Mypackage" gibi göreli değil
wlredeye

Bu, geçerli dizine göre içe aktarmayla ilgili düzelttiğiniz bölümle ilgilidir. Evet, tüm kullanıcı içe aktarmaları ile ilgilidir $GOPATH/src.
JimB

5

Yerel paket hareket halindeyken can sıkıcı bir sorundur.

Şirketimizdeki bazı projeler için alt paketler kullanmamaya karar veriyoruz.

  • $ glide install
  • $ go get
  • $ go install

Bütün iş.

Bazı projeler için alt paketler kullanıyoruz ve yerel paketleri tam yolla içe aktarıyoruz:

import "xxxx.gitlab.xx/xxgroup/xxproject/xxsubpackage

Ancak bu projeyi çatallaştırırsak, alt paketler hala orijinal olanı ifade eder.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.