我想将项目分解为子文件夹。
我想要这个代码结构:
├── main.go
└── models
└── user.go
main.go是:
package main
import (
"fmt"
"./models"
)
func main(){
fmt.Println(User{"new_user"})
}
user.go是:
package models
type User struct {
Login string
}
但是主程序包中没有定义用户,并且导入引发警告“已导入但未使用”。
我做错了什么?我的项目很简单(不是这样的例子,只是文件很少(控制器和模型)),我想要一个简单的结构。
也许我是以完全错误的方式做到的?
答案 0 :(得分:9)
我最近通过使用 go模块实现了这一目标。
Golang从go v1.11.1开始引入了对模块的初步选择加入支持,这旨在完全消除荒谬的$GOPATH
的必要性。现在,您不仅可以在任何普通目录(例如~/development
中都拥有版本化的依赖项,而且基本上可以拥有类似于名称空间和子目录的外观。您可以通过使用以下环境变量调用go命令来enable this feature:{1}
Go v1.11.3预计会enable modules by default,并将于2019年8月推出。
这是示例目录结构(您可能会在其他语言中找到它们)。
GO111MODULE=on
该应用程序称为~/Dev/my-app
├── src/
│ ├── one/
│ │ ├── two/
│ │ │ └── two.go
│ │ └── one.go
│ └── zero.go
├── go.mod
└── app.go
,它将是my-app
的模块名称。我们在app.go
中定义了一次,然后子目录中的所有其他go文件都将自动导入,就好像它们是命名空间一样。
鉴于以上情况,假设go.mod
包含一个名为two.go
的函数,则可以使用Two
将其导入app.go
中。
这是您需要实现的目标:
my-app/src/one/two
module my-app
package two
func Two() string {
return "I'm totally not supposed to be using go modules for this"
}
如果要将另一个文件放在2 /中,则只要在新文件中使package main
import "my-app/src/one/two"
func main() {
two.Two()
}
可用,就只需使用two.TheNewFunc()
。
我创建了一个非常简单的GitHub repo,您可以作为示例进行查看。
答案 1 :(得分:6)
您的导入应该是绝对的:
import "github.com/abonec/go_import_problem/models"
如果您不想将项目导出到外部参照,可以执行以下操作:
import "go_import_problem/models"
(即:“the name of your project folder accessible by GOPATH/your package
”)
请参阅“How to use custom packages in golang?”。
你会使用:
models.User
如Effective Go中所述:
包的导入者将使用该名称来引用其内容,因此包中的导出名称可以使用该事实来避免口吃。
(不要使用导入.
表示法,这可以简化必须在他们正在测试的包之外运行的测试,否则应该避免。)
重申一下, Go包的名称总是绝对的(也就是说,没有相对的包名,既没有
./
也没有../
或类似的东西)但是这些名称“锚定”到$GOPATH
中列出的所谓工作区之一。当Go搜索包时,它会查看工作区并尝试按顺序查找每个包中的包。
搜索不是递归的 不,不需要在包路径中对URL进行编码 - 除非您想要将包公开。
答案 2 :(得分:0)
您需要通过包名称
来限定包中的商品所以
fmt.Println(models.User{"new_user"})
答案 3 :(得分:0)
将单个项目分解为子文件夹不是构建go项目的推荐方法,这就是为什么基本上没有好的方法来做你想要的。
如果项目非常大而且太难以制作单个包,请考虑将其拆分为几个完全不同的包,而不是特殊的子目录包。这样做的好处是可以强制您仔细思考内部API。
答案 4 :(得分:0)
在与“ go / src”文件夹相关的代码中引用了软件包
└── go
└── src
└── myAwesomeProject
├── main.go
└── models
└── user.go
所以在main.go
package main
import (
"fmt"
"myAwesomeProject/models"
)
类似地,程序包可以使用相同的约定相互引用。
答案 5 :(得分:-5)
您应该按照导入的名称使用导入的对象。例如,如果你
import "./models"
使用struct User,您应该将其用作
models.User