试图了解如何在我的项目和包中找到结构

时间:2018-02-06 01:59:18

标签: go

在我的main.go中,我试图引用一个结构,我收到一个错误:

  

undefined:UserService

/main.go with package main

userService := &UserService{}

/services/user_service.go with package main

type UserService struct {
  // ..
}

为什么找不到我的结构? 我可以将我的/ services文件放在不同的包中吗?如果是这样,那么我将如何在main.go文件中引用它们?

1 个答案:

答案 0 :(得分:1)

  

我正在使用go run main.go运行它。

这是一个问题。 go run main.go只会构建main.go。对于包含多个文件的项目,请使用go build。然后它将找到您的源文件并构建它们。但这不会起作用,因为你没有遵循源布局的Go约定。

go工具强制执行一种非常特殊的方式来构建项目。您可以在How To Write Go Code中了解相关信息。通常,源代码树是平的。 go build根本找不到services/user_service.go。您可以使用go build -x来查看此内容。

$ tree
.
├── main.go
└── service
    └── user_service.go

1 directory, 2 files

$ go build -x
WORK=/var/folders/0b/7xp2lxbd7yl0tcpms06fr3d40000gn/T/go-build148902279
mkdir -p $WORK/soq/_obj/
mkdir -p $WORK/soq/_obj/exe/
cd /Users/schwern/go/src/soq
/opt/local/lib/go/pkg/tool/darwin_amd64/compile -o $WORK/soq.a -trimpath $WORK -goversion go1.9.3 -p main -complete -buildid 08f76ca23c0110836288d4a2c698c2692588f909 -D _/Users/schwern/go/src/soq -I $WORK -pack ./main.go
# soq
./main.go:8:21: undefined: UserService

请注意,compile仅适用于main.go

简单的解决方案是展平您的源代码树。

$ tree
.
├── main.go
└── user_service.go

0 directories, 2 files

$ go build -x
WORK=/var/folders/0b/7xp2lxbd7yl0tcpms06fr3d40000gn/T/go-build117658131
mkdir -p $WORK/soq/_obj/
mkdir -p $WORK/soq/_obj/exe/
cd /Users/schwern/go/src/soq
/opt/local/lib/go/pkg/tool/darwin_amd64/compile -o $WORK/soq.a -trimpath $WORK -goversion go1.9.3 -p main -complete -buildid 8dfd03a3d0d09267ebc5ff9d1b8dd630d7465e9c -D _/Users/schwern/go/src/soq -I $WORK -pack ./main.go ./user_service.go
cd .
/opt/local/lib/go/pkg/tool/darwin_amd64/link -o $WORK/soq/_obj/exe/a.out -L $WORK -extld=/usr/bin/clang -buildmode=exe -buildid=8dfd03a3d0d09267ebc5ff9d1b8dd630d7465e9c $WORK/soq.a
mv $WORK/soq/_obj/exe/a.out soq

现在它运作正常。

你可能会想" 但是如果我想做更复杂的事情该怎么办?"

可以编写自己的构建工具,该工具遍历子目录以查找所有Go文件并将其提供给go build。但这违背了Go的本质,随着时间的推移,你会发现自己不得不颠覆越来越多的工具。

Go是故意设计的,以阻止复杂性。具有子目录的大型源代码树会增加复杂性并允许纠缠的子系统,因此go工具无法帮助您。 (Go语言不关心您的文件结构,只关心go构建工具)。

相反,Go处理此问题的方法是将services拆分为新的包。以明确的界限开发它,并且没有将它与其他系统耦合的诱惑,并import将它放入主包中。