Go에서 로컬 패키지를 가져 오는 방법은 무엇입니까?


90

저는 처음으로 현지화하려는 예제 코드를 작성하고 있습니다.

원래 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 문을 다음과 같이 변환했습니다.

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

또한, 나는 사용할 때 commonrouters대신 ./common./routersimport 문에, 내가 얻을 :

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 코드 작성 방법"을 참조하십시오 .
JimB

21
@JimB는 철학적 논쟁을 제쳐두고 위에서 언급 한 문제를 해결하는 방법에 관심이 있습니다.
Karlom

3
나는 철학적 인 진술을하려고하는 것이 아니라, 말 그대로 모든 임포트가 로컬 파일 시스템에서 발생 한다고 말하는 것입니다. 원격 저장소에서 시작되었는지 여부에 관계없이 차이가 없습니다. 상대 경로 (때로는 작동하지만 권장하지 않음)를 사용하지 말고 "Go 코드 작성 방법"문서, 특히 "코드 구성" 섹션을 참조하십시오 .
JimB

답변:


63

글쎄, 나는 문제를 알아 냈다. 기본적으로 가져 오기 시작 경로는$HOME/go/src

따라서 myapp패키지 이름 앞에 추가 해야합니다. 즉, 가져 오기는 다음과 같아야합니다.

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

3
프로젝트 이름을 사용 myapp하는 것은 나쁜 생각입니다. 예를 들어 프로젝트 이름을 변경하면 모든 가져 오기가 실패합니다
TomSawyer

7
대안은 무엇입니까? Go는 상대 가져 오기를 사용하는 것을 권장하지 않습니다.
Sam Holmes

11
물론 프로젝트 이름을 변경하면 모든 가져 오기가 실패합니다. 프로젝트 이름은 거의 변경되지 않습니다.
Damien Roche

21
음, go1.11부터는 새로운 모듈 시스템을 사용할 수 있습니다. go mod init <module_name>그리고 그냥 import "<module_name>/<pkg_name>".
비명

.go 파일에서 github.com/dgrijalva/jwt-go를 어떻게 가져올 수 있습니까? 내 jwt-go 폴더는 src / github.com / dgrijalva 안에 있습니다
Manik Thakur

30

위의 Go 1.5를 사용하는 경우 공급 업체 기능을 사용해 볼 수 있습니다 . 로컬 패키지를 공급 업체 폴더 에 넣고 더 짧은 경로로 가져올 수 있습니다. 귀하의 경우에는 공급 업체 폴더 안에 commonrouters 폴더를 넣을 수 있습니다.

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

다음과 같이 가져옵니다.

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

Go는 $ GOPATH / src 대신 프로젝트의 공급 업체 디렉토리 (최소 하나의 .go 파일이있는 경우)에서 시작하여 패키지를 조회하려고 시도하기 때문에 작동합니다.

참고 :이 기능을 사용하면 패키지에 대한 "모든 종속성 코드"를 자신의 프로젝트 디렉터리에 넣을 수 있으므로 모든 빌드에 대해 항상 동일한 종속성 버전을 얻을 수 있으므로 공급 업체와 더 많은 작업을 수행 할 수 있습니다. python의 npm 또는 pip와 비슷하지만 프로젝트에 종속성을 수동으로 복사해야합니다.

이 기능에 대한 자세한 내용을 보려면 여기를 찾아보십시오.

공급 업체 폴더 이해 및 사용 by Daniel Theophanes

Lucas Fernandes da Costa의 Go 종속성 관리 이해

당신이나 다른 누군가가 도움이 되었기를 바랍니다.


18

가져 오기 경로는 $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.