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

In my main.go I am trying to reference a struct, I'm getting a error:

undefined: UserService

/main.go with package main

userService := &UserService{}

/services/user_service.go with package main

type UserService struct {
  // ..
}

Why can't it find my struct? Can I put my /services files in a different package? If so, then how would I reference them in my main.go file?

I am running it using go run main.go.

That's a problem. go run main.go will only build main.go. For a project that is more than one file, use go build. It will then find your source files and build them. But that isn't going to work either because you're not following the Go conventions for source layout.

The go tool enforces a very particular way of structuring your project. You can read about this in How To Write Go Code. In general, the source code tree is flat. go build is simply not finding services/user_service.go. You can see this with 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

Note that compile is only working on main.go.

The simple solution is to flatten your source tree.

$ 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

And now it works fine.


You might be thinking "but what if I want to do more complicated things?"

You could write your own build tool that walked sub-directories to find all the Go files and feed them to go build. But that goes against the nature of Go, and you'll find yourself having to subvert more and more tools as time goes on.

Go is deliberately designed to discourage complexity. Large source trees with subdirectories encourage complexity and allow entangled subsystems, so the go tool does not help you with them. (The Go language does not care about your file structure, just the go build tool).

Instead, the Go way to deal with this is to split your services off into a new package. Develop it with clear boundaries, and without the temptation to couple it to other systems, and import it into your main package.