将项目拆分为子文件夹

时间:2014-04-18 13:11:40

标签: go

我想将项目分解为子文件夹。

我想要这个代码结构:

├── 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
}

但是主程序包中没有定义用户,并且导入引发警告“已导入但未使用”。

我做错了什么?我的项目很简单(不是这样的例子,只是文件很少(控制器和模型)),我想要一个简单的结构。

也许我是以完全错误的方式做到的?

问题项目在这里:https://github.com/abonec/go_import_problem

6 个答案:

答案 0 :(得分:9)

我最近通过使用 go模块实现了这一目标。

Golang从go v1.11.1开始引入了对模块的初步选择加入支持,这旨在完全消除荒谬的$GOPATH的必要性。现在,您不仅可以在任何普通目录(例如~/development中都拥有版本化的依赖项,而且基本上可以拥有类似于名称空间和子目录的外观。您可以通过使用以下环境变量调用go命令来enable this feature 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中。

这是您需要实现的目标:

go.mod

my-app/src/one/two

two.go

module my-app

app.go

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中所述:

  

包的导入者将使用该名称来引用其内容,因此包中的导出名称可以使用该事实来避免口吃。
  (不要使用导入.表示法,这可以简化必须在他们正在测试的包之外运行的测试,否则应该避免。)


kostix添加in the comments

  

重申一下, 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