missing dot in first path element問題解決
技術就是一層窗戶紙,能捅破便是撥開雲天見月明,捅不破就是一葉障目,不見泰山呀!
今天碰到了個問題,卡了我半天。
malformed module path "XXXX": missing dot in first path element
問題原因
因為在 go1.13 中, go module 名稱規范要求路徑的第一部分必須滿足域名規范,否則可能匯報類似
malformed module path "xxxx": missing dot in first path element
這樣的錯誤。
解決方法
使用go mod 的replace語句對相關的包進行替換。
項目的目錄結構:
kafka模塊的go mod:
taillog模塊的go mod:
main包的go mod:
替換之前他會報錯,說找不到http://github.com/wind-zhou/logagent/kafka這個包,經過relace替換后便編譯成功。
我這里具體的機理還沒有弄明白,但我猜測他可能會以為引入的包是第三方的包,因此回去GitHub上找,用replace之后,便告訴編譯器這個包在本地。
下面對go mod的本地的包的操作進行詳細解釋。
go mod 如何導入本地的包
接下來的內容轉載自:
https://www.liwenzhou.com/posts/Go/import_local_package_in_go_module/
go module
是Go1.11版本之后官方推出的版本管理工具,並且從Go1.13
版本開始,go module
將是Go語言默認的依賴管理工具。到今天Go1.14
版本推出之后Go modules
功能已經被正式推薦在生產環境下使用了。
這幾天已經有很多教程講解如何使用go module
,以及如何使用go module
導入gitlab私有倉庫,我這里就不再啰嗦了。但是最近我發現很多小伙伴在群里問如何使用go module
導入本地包,作為初學者大家剛開始接觸package的時候肯定都是先在本地創建一個包,然后本地調用一下,然后就被卡住了。。。
這里就詳細介紹下如何使用go module
導入本地包。
前提
假設我們現在有moduledemo
和mypackage
兩個包,其中moduledemo
包中會導入mypackage
包並使用它的New
方法。
mypackage/mypackage.go
內容如下:
package mypackage
import "fmt"
func New(){
fmt.Println("mypackage.New")
}
我們現在分兩種情況討論:
在同一個項目下
注意:在一個項目(project)下我們是可以定義多個包(package)的。
目錄結構
現在的情況是,我們在moduledemo/main.go
中調用了mypackage
這個包。
moduledemo
├── go.mod
├── main.go
└── mypackage
└── mypackage.go
導入包
這個時候,我們需要在moduledemo/go.mod
中按如下定義:
module moduledemo
go 1.14
然后在moduledemo/main.go
中按如下方式導入mypackage
package main
import (
"fmt"
"moduledemo/mypackage" // 導入同一項目下的mypackage包
)
func main() {
mypackage.New()
fmt.Println("main")
}
舉個例子
舉一反三,假設我們現在有文件目錄結構如下:
└── bubble
├── dao
│ └── mysql.go
├── go.mod
└── main.go
其中bubble/go.mod
內容如下:
module github.com/q1mi/bubble
go 1.14
bubble/dao/mysql.go
內容如下:
package dao
import "fmt"
func New(){
fmt.Println("mypackage.New")
}
bubble/main.go
內容如下:
package main
import (
"fmt"
"github.com/q1mi/bubble/dao"
)
func main() {
dao.New()
fmt.Println("main")
}
不在同一個項目下
目錄結構
├── moduledemo
│ ├── go.mod
│ └── main.go
└── mypackage
├── go.mod
└── mypackage.go
導入包
這個時候,mypackage
也需要進行module初始化,即擁有一個屬於自己的go.mod
文件,內容如下:
module mypackage
go 1.14
然后我們在moduledemo/main.go
中按如下方式導入:
import (
"fmt"
"mypackage"
)
func main() {
mypackage.New()
fmt.Println("main")
}
因為這兩個包不在同一個項目路徑下,你想要導入本地包,並且這些包也沒有發布到遠程的github或其他代碼倉庫地址。這個時候我們就需要在go.mod
文件中使用replace
指令。
在調用方也就是packagedemo/go.mod
中按如下方式指定使用相對路徑來尋找mypackage
這個包。
module moduledemo
go 1.14
require "mypackage" v0.0.0
replace "mypackage" => "../mypackage"
舉個例子
最后我們再舉個例子鞏固下上面的內容。
我們現在有文件目錄結構如下:
├── p1
│ ├── go.mod
│ └── main.go
└── p2
├── go.mod
└── p2.go
p1/main.go
中想要導入p2.go
中定義的函數。
p2/go.mod
內容如下:
module liwenzhou.com/q1mi/p2
go 1.14
p1/main.go
中按如下方式導入
import (
"fmt"
"liwenzhou.com/q1mi/p2"
)
func main() {
p2.New()
fmt.Println("main")
}
因為我並沒有把liwenzhou.com/q1mi/p2
這個包上傳到liwenzhou.com
這個網站,我們只是想導入本地的包,這個時候就需要用到replace
這個指令了。
p1/go.mod
內容如下:
module github.com/q1mi/p1
go 1.14
require "liwenzhou.com/q1mi/p2" v0.0.0
replace "liwenzhou.com/q1mi/p2" => "../p2"
此時,我們就可以正常編譯p1
這個項目了。
說再多也沒用,自己動手試試吧。