How to use “internal” packages?

前端 未结 4 1312
时光说笑
时光说笑 2020-12-09 07:50

I try understand how to organize go code using \"internal\" packages. Let me show what the structure I have:

project/
  internal/
    foo/
      foo.go # pac         


        
4条回答
  •  心在旅途
    2020-12-09 08:25

    With modules introduction in Go v1.11 and above you don't have to specify your project path in $GOPATH/src

    You need to tell Go about where each module located by creating go.mod file. Please refer to go help mod documentation.

    Here is an example of how to do it:

    project
    |   go.mod
    |   main.go
    |
    \---internal
        +---bar
        |       bar.go
        |       go.mod
        |
        \---foo
                foo.go
                go.mod
    

    project/internal/bar/go.mod

    module bar
    
    go 1.14
    

    project/internal/bar/bar.go

    package bar
    
    import "fmt"
    
    //Bar prints "Hello from Bar"
    func Bar() {
        fmt.Println("Hello from Bar")
    }
    
    

    project/internal/foo/go.mod

    module foo
    
    go 1.14
    

    project/internal/foo/foo.go

    package foo
    
    import "fmt"
    
    //Foo prints "Hello from Foo"
    func Foo() {
        fmt.Println("Hello from Foo")
    }
    

    project/main.go

    package main
    
    import (
        "internal/bar"
        "internal/foo"
    )
    
    func main() {
        bar.Bar()
        foo.Foo()
    }
    
    

    Now the most important module project/go.mod

    module project
    
    go 1.14
    
    
    require internal/bar v1.0.0
    replace internal/bar => ./internal/bar
    require internal/foo v1.0.0
    replace internal/foo => ./internal/foo
    
    

    Couple things here:

    1. You can have any name in require. You can have project/internal/bar if you wish. What Go think it is URL address for the package, so it will try to pull it from web and give you error
    go: internal/bar@v1.0.0: malformed module path "internal/bar": missing dot in first path element
    

    That is the reason why you need to have replace where you tell Go where to find it, and that is the key!

    replace internal/bar => ./internal/bar
    
    1. The version doesn't matter in this case. You can have v0.0.0 and it will work.

    Now, when you execute your code you will have

    Hello from Bar
    Hello from Foo
    

    Here is GitHub link for this code example

提交回复
热议问题