จะนำเข้าแพ็คเกจท้องถิ่นได้อย่างไร?


101

ฉันเพิ่งเริ่มใช้งานโค้ดตัวอย่างที่ต้องการแปลเป็นภาษาท้องถิ่น

ในmain.goคำสั่งนำเข้าดั้งเดิมคือ:

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

ตอนนี้ฉันมีcommonและroutersแพคเกจใน/home/me/go/src/myapp

ดังนั้นฉันจึงแปลงคำสั่งนำเข้าเป็น:

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

แต่เมื่อฉันเรียกใช้go install myappฉันได้รับข้อผิดพลาดเหล่านี้:

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

นอกจากนี้เมื่อฉันใช้commonและroutersแทน./commonและ./routersในคำสั่งนำเข้าฉันจะได้รับ:

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)

ฉันจะแก้ไขปัญหานี้ได้อย่างไร?


5
การนำเข้าทั้งหมดเป็น "ภายใน" โดยไม่คำนึงถึงเส้นทางการนำเข้า ดู"วิธีการเขียน Go Code"สำหรับคำอธิบายโดยละเอียด
JimB

24
@JimB ละทิ้งการถกเถียงทางปรัชญาสิ่งที่ฉันกังวลคือวิธีแก้ปัญหาดังกล่าวข้างต้น
Karlom

3
ฉันไม่ได้พยายามสร้างคำพูดเชิงปรัชญาฉันกำลังบอกว่าการนำเข้าทั้งหมดเกิดขึ้นในระบบไฟล์ภายในของคุณ ไม่มีความแตกต่างใด ๆ ไม่ว่าจะมาจาก repo ระยะไกลหรือไม่ก็ตาม อย่าพยายามที่จะใช้เส้นทางญาติ (ที่พวกเขาทำงานบางครั้ง แต่มีกำลังใจ) และไปผ่าน "วิธีการเขียนโค้ดไป" เอกสารโดยเฉพาะส่วนที่เกี่ยวกับ"องค์กร" รหัส
JimB

คำตอบ:


70

ฉันพบปัญหาแล้ว โดยทั่วไปไปเส้นทางเริ่มต้นสำหรับการนำเข้าคือ$HOME/go/src

ดังนั้นฉันแค่ต้องเพิ่มmyappหน้าชื่อแพ็คเกจนั่นคือการนำเข้าควรเป็น:

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

4
การใช้ชื่อโครงการเช่นmyappนี้เป็นความคิดที่ไม่ดีเช่นหากคุณเปลี่ยนชื่อโครงการการนำเข้าทั้งหมดจะล้มเหลว
TomSawyer

9
ทางเลือกคืออะไร? Go ไม่แนะนำให้คุณใช้การนำเข้าแบบสัมพัทธ์
Sam Holmes

12
แน่นอนการนำเข้าทั้งหมดจะล้มเหลวหากคุณเปลี่ยนชื่อโครงการ ชื่อโครงการไม่ค่อยเปลี่ยน
Damien Roche

23
ณ go1.11 คุณสามารถใช้ระบบโมดูลใหม่ได้ go mod init <module_name>แล้วก็แค่import "<module_name>/<pkg_name>".
ร้องเสียงหลง

เราจะนำเข้า github.com/dgrijalva/jwt-go ในไฟล์. go ได้อย่างไร? โฟลเดอร์ jwt-go ของฉันอยู่ใน src / github.com / dgrijalva
Manik Thakur

34

หากคุณใช้ Go 1.5 ข้างต้นคุณสามารถลองใช้คุณสมบัติการขายได้ ช่วยให้คุณสามารถวางแพ็คเกจภายในเครื่องของคุณไว้ในโฟลเดอร์ผู้ขายและนำเข้าด้วยเส้นทางที่สั้นกว่า ในกรณีของคุณคุณสามารถใส่โฟลเดอร์commonและrouterไว้ในโฟลเดอร์vendorได้

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

แล้วนำเข้าแบบนี้

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

วิธีนี้ใช้ได้ผลเพราะ Go จะพยายามค้นหาแพ็กเกจของคุณโดยเริ่มจากไดเรกทอรีผู้ขายของโปรเจ็กต์ของคุณ (หากมีไฟล์. go อย่างน้อยหนึ่งไฟล์) แทนที่จะเป็น $ GOPATH / src

FYI: คุณสามารถทำสิ่งต่างๆกับผู้ขายได้มากขึ้นเนื่องจากคุณลักษณะนี้ช่วยให้คุณสามารถใส่ "รหัสอ้างอิงทั้งหมดของคุณ" สำหรับแพ็คเกจภายในไดเร็กทอรีของโปรเจ็กต์ของคุณเองดังนั้นจึงสามารถรับเวอร์ชันอ้างอิงเดียวกันสำหรับทุกบิลด์ได้เสมอ มันเหมือนกับ npm หรือ pip ใน python แต่คุณต้องคัดลอกการอ้างอิงไปยังโปรเจ็กต์ของคุณด้วยตนเองหรือถ้าคุณต้องการทำให้ง่ายลองดู govendor โดย Daniel Theophanes

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับคุณลักษณะนี้โปรดดูที่นี่

การทำความเข้าใจและการใช้โฟลเดอร์ผู้ขายโดย Daniel Theophanes

การทำความเข้าใจ Go Dependency Management โดย Lucas Fernandes da Costa

ฉันหวังว่าคุณหรือคนอื่นจะพบว่ามันเป็นประโยชน์


19

เส้นทางการนำเข้าสัมพันธ์กับตัวแปรสภาพแวดล้อม$GOPATHและของคุณ $GOROOTตัวอย่างเช่นมีดังต่อไปนี้$GOPATH:

GOPATH=/home/me/go

แพ็คเกจที่อยู่ใน/home/me/go/src/lib/commonและ/home/me/go/src/lib/routersนำเข้าตามลำดับดังนี้:

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

ใช่ตัวอย่างแรกคือความผิดพลาดของฉัน
wlredeye

คุณหมายถึงอะไรโดยเส้นทางสัมพัทธ์ที่เครื่องมือไม่รองรับ
wlredeye

2
คุณไม่สามารถgo installแพคเกจที่ใช้การนำเข้าแบบสัมพัทธ์
JimB

ฉันคิดว่ามันเข้าใจผิดที่นี่ ฉันหมายถึงเทียบกับ GOPATH ไม่ใช่แค่ญาติอย่าง "../../mypackage"
wlredeye

นั่นคือการอ้างอิงถึงส่วนที่คุณแก้ไขเกี่ยวกับการนำเข้าที่สัมพันธ์กับไดเร็กทอรีปัจจุบัน $GOPATH/srcใช่การนำเข้าของผู้ใช้ทั้งหมดเป็นญาติกับ
JimB

5

แพคเกจภายในเครื่องเป็นปัญหาที่น่ารำคาญในระหว่างการเดินทาง

สำหรับบางโครงการใน บริษัท ของเราเราตัดสินใจที่จะไม่ใช้แพ็คเกจย่อยเลย

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

งานทั้งหมด.

สำหรับบางโปรเจ็กต์เราใช้แพ็กเกจย่อยและนำเข้าแพ็กเกจโลคัลพร้อมพา ธ แบบเต็ม:

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

แต่ถ้าเราแยกโปรเจ็กต์นี้แพ็กเกจย่อยจะยังคงอ้างอิงโปรเจ็กต์เดิม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.