go mod 如何导入本地的包
<h1 id="missing-dot-in-first-path-element问题解决">missing dot in first path element问题解决</h1><blockquote>
<p>技术就是一层窗户纸,能捅破便是拨开云天见月明,捅不破就是一叶障目,不见泰山呀!</p>
</blockquote>
<p>今天碰到了个问题,卡了我半天。</p>
<blockquote>
<p>malformed module path "XXXX": missing dot in first path element</p>
</blockquote>
<h2 id="问题原因">问题原因</h2>
<p>因为在 go1.13 中, go module 名称规范要求路径的第一部分必须满足域名规范,否则可能汇报类似</p>
<p><code>malformed module path "xxxx": missing dot in first path element</code> 这样的错误。</p>
<h2 id="解决方法">解决方法</h2>
<p>使用go mod 的replace语句对相关的包进行替换。</p>
<p><strong>项目的目录结构:</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1976539/202005/1976539-20200504000335337-334245768.png" alt="" loading="lazy"></p>
<p><strong>kafka模块的go mod:</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1976539/202005/1976539-20200504000409505-1850401995.png" alt="" loading="lazy"></p>
<p><strong>taillog模块的go mod:</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1976539/202005/1976539-20200504000448132-161702928.png" alt="" loading="lazy"></p>
<p><strong>main包的go mod:</strong></p>
<p><img src="https://img2020.cnblogs.com/blog/1976539/202005/1976539-20200504000522721-1034484163.png" alt="" loading="lazy"></p>
<p>替换之前他会报错,说找不到http://github.com/wind-zhou/logagent/kafka这个包,经过relace替换后便编译成功。</p>
<blockquote>
<p>我这里具体的机理还没有弄明白,但我猜测他可能会以为引入的包是第三方的包,因此回去GitHub上找,用replace之后,便告诉编译器这个包在本地。</p>
</blockquote>
<p>下面对go mod的本地的包的操作进行详细解释。</p>
<h1 id="go-mod-如何导入本地的包">go mod 如何导入本地的包</h1>
<blockquote>
<p>接下来的内容转载自:<br>
https://www.liwenzhou.com/posts/Go/import_local_package_in_go_module/</p>
</blockquote>
<p><code>go module</code>是Go1.11版本之后官方推出的版本管理工具,并且从<code>Go1.13</code>版本开始,<code>go module</code>将是Go语言默认的依赖管理工具。到今天<code>Go1.14</code>版本推出之后<code>Go modules</code> 功能已经被正式推荐在生产环境下使用了。</p>
<p>这几天已经有很多教程讲解如何使用<code>go module</code>,以及如何使用<code>go module</code>导入gitlab私有仓库,我这里就不再啰嗦了。但是最近我发现很多小伙伴在群里问如何使用<code>go module</code>导入本地包,作为初学者大家刚开始接触package的时候肯定都是先在本地创建一个包,然后本地调用一下,然后就被卡住了。。。</p>
<p>这里就详细介绍下如何使用<code>go module</code>导入本地包。</p>
<h2 id="前提">前提</h2>
<p>假设我们现在有<code>moduledemo</code>和<code>mypackage</code>两个包,其中<code>moduledemo</code>包中会导入<code>mypackage</code>包并使用它的<code>New</code>方法。</p>
<p><code>mypackage/mypackage.go</code>内容如下:</p>
<pre><code>package mypackage
import "fmt"
func New(){
fmt.Println("mypackage.New")
}
</code></pre>
<p>我们现在分两种情况讨论:</p>
<h2 id="在同一个项目下">在同一个项目下</h2>
<p><strong>注意</strong>:在一个项目(project)下我们是可以定义多个包(package)的。</p>
<h3 id="目录结构">目录结构</h3>
<p>现在的情况是,我们在<code>moduledemo/main.go</code>中调用了<code>mypackage</code>这个包。</p>
<pre><code>moduledemo
├── go.mod
├── main.go
└── mypackage
└── mypackage.go
</code></pre>
<h3 id="导入包">导入包</h3>
<p>这个时候,我们需要在<code>moduledemo/go.mod</code>中按如下定义:</p>
<pre><code>module moduledemo
go 1.14
</code></pre>
<p>然后在<code>moduledemo/main.go</code>中按如下方式导入<code>mypackage</code></p>
<pre><code>package main
import (
"fmt"
"moduledemo/mypackage"// 导入同一项目下的mypackage包
)
func main() {
mypackage.New()
fmt.Println("main")
}
</code></pre>
<h3 id="举个例子">举个例子</h3>
<p>举一反三,假设我们现在有文件目录结构如下:</p>
<pre><code>└── bubble
├── dao
│ └── mysql.go
├── go.mod
└── main.go
</code></pre>
<p>其中<code>bubble/go.mod</code>内容如下:</p>
<pre><code>module github.com/q1mi/bubble
go 1.14
</code></pre>
<p><code>bubble/dao/mysql.go</code>内容如下:</p>
<pre><code>package dao
import "fmt"
func New(){
fmt.Println("mypackage.New")
}
</code></pre>
<p><code>bubble/main.go</code>内容如下:</p>
<pre><code>package main
import (
"fmt"
"github.com/q1mi/bubble/dao"
)
func main() {
dao.New()
fmt.Println("main")
}
</code></pre>
<h2 id="不在同一个项目下">不在同一个项目下</h2>
<h3 id="目录结构-1">目录结构</h3>
<pre><code>├── moduledemo
│ ├── go.mod
│ └── main.go
└── mypackage
├── go.mod
└── mypackage.go
</code></pre>
<h3 id="导入包-1">导入包</h3>
<p>这个时候,<code>mypackage</code>也需要进行module初始化,即拥有一个属于自己的<code>go.mod</code>文件,内容如下:</p>
<pre><code>module mypackage
go 1.14
</code></pre>
<p>然后我们在<code>moduledemo/main.go</code>中按如下方式导入:</p>
<pre><code>import (
"fmt"
"mypackage"
)
func main() {
mypackage.New()
fmt.Println("main")
}
</code></pre>
<p><strong>因为这两个包不在同一个项目路径下,你想要导入本地包,并且这些包也没有发布到远程的github或其他代码仓库地址。这个时候我们就需要在<code>go.mod</code>文件中使用<code>replace</code>指令</strong>。</p>
<p>在调用方也就是<code>packagedemo/go.mod</code>中按如下方式指定使用相对路径来寻找<code>mypackage</code>这个包。</p>
<pre><code>module moduledemo
go 1.14
require "mypackage" v0.0.0
replace "mypackage" => "../mypackage"
</code></pre>
<h3 id="举个例子-1">举个例子</h3>
<p>最后我们再举个例子巩固下上面的内容。</p>
<p>我们现在有文件目录结构如下:</p>
<pre><code>├── p1
│ ├── go.mod
│ └── main.go
└── p2
├── go.mod
└── p2.go
</code></pre>
<p><code>p1/main.go</code>中想要导入<code>p2.go</code>中定义的函数。</p>
<p><code>p2/go.mod</code>内容如下:</p>
<pre><code>module liwenzhou.com/q1mi/p2
go 1.14
</code></pre>
<p><code>p1/main.go</code>中按如下方式导入</p>
<pre><code>import (
"fmt"
"liwenzhou.com/q1mi/p2"
)
func main() {
p2.New()
fmt.Println("main")
}
</code></pre>
<p>因为我并没有把<code>liwenzhou.com/q1mi/p2</code>这个包上传到<code>liwenzhou.com</code>这个网站,我们只是想导入本地的包,这个时候就需要用到<code>replace</code>这个指令了。</p>
<p><code>p1/go.mod</code>内容如下:</p>
<pre><code>module github.com/q1mi/p1
go 1.14
require "liwenzhou.com/q1mi/p2" v0.0.0
replace "liwenzhou.com/q1mi/p2" => "../p2"
</code></pre>
<p>此时,我们就可以正常编译<code>p1</code>这个项目了。</p>
<p>说再多也没用,自己动手试试吧。</p>
</div>
<div id="MySignature" role="contentinfo">
生活是一首长长的歌!<br><br>
来源:https://www.cnblogs.com/wind-zhou/p/12824857.html
頁:
[1]