4

Note: I've seen other questions related to this topic but none that address the issue at hand.

I'm struggling to organize my Go code. I'm writing a daemon and I would like to split the code logically between files.

Say I have 3 files, main.go:

package main

func main() {
    GlobalFunc()

    commonFunc()

    var svr server.Server
    server.OtherFunc()
}

server.go:

package main

type Server struct {
    name string
    ip string
}

func GlobalFunc() {

}

func (s *Server) OtherFunc() {
    commonFunc()
}

and common.go:

package main

func commonFunc() {

}

I would like to be able to call GlobalFunc() as server.GlobalFunc() to show it's part of the "server module". That doesn't seem possible with the above example.

I could make a subdir server, put server.go in there, and change it to package server. The problem here is that I can't seem to shared common.go between the main and the server package. I understand why, it doesn't seem like a good idea either.

So I am missing something simple here and making this more complicated?

Thanks!

marcantonio
  • 958
  • 10
  • 24
  • 2
    possible duplicate of [What is a sensible way to layout a Go project](http://stackoverflow.com/questions/14867452/what-is-a-sensible-way-to-layout-a-go-project) – Not_a_Golfer Apr 21 '15 at 17:39
  • 2
    In general - if it's just a small app, keep everything in one package. once you separate your server into a different package, you'll need to move common functions to a 3rd package to avoid cyclic imports. – Not_a_Golfer Apr 21 '15 at 17:40
  • Yeah, that's what I'm finding. I moved `common` into a separate package. This solves the problem but doesn't _feel_ right. – marcantonio Apr 21 '15 at 17:46
  • 2
    Also note that [idiomatic naming](https://blog.golang.org/package-names) would be different for things in `server.go` depending on if it was in `main` or a `server` package. In former `type Server …` is fine whereas in the later it means stuttering with `server.Server` whenever used. E.g. the `errors` package has a `New` function called as `errors.New` whereas if you put something like that locally in your own package you'd call it something like `NewError` or somesuch. – Dave C Apr 21 '15 at 17:47

1 Answers1

2

I think it's fair assumption you'd like to use some common methods across your projects. The same way you separate the server, you should then separate the package with the common methods. Although it's probably better to think and organise it in some logical way, rather than calling the package tools, misc etc.

I tend to split things into packages, so they can be used in other places, while the main package would be simply flag parsing and calling the library methods, for example server.Run(). Other people like to put everything into the main project, which might be all right if you think people would use your project as a command line tool, rather than a package.

I would consider:

deamon/
    main.go
    server/server.go
    somelib/somelib.go -- to be included from main and server

If you would like your project to be used mainly as a package, but still include some command line utility, you might consider:

deamon/
   deamon.go -- package deamon
   deamond/
       main.go -- you may include the top level package as anyone else

We need to remember that in Go you include your packages with an absolute path, so you can keep your "common" stuff anywhere in the project, or if you decide is useful by itself, just release a separate, standalone project.

tomasz
  • 12,574
  • 4
  • 43
  • 54
  • I think this is probably the best way. I just feels a little clunky. I really just wanted to be sure I wasn't missing something obvious to others. I agree with your different approaches depending on the intent of the package. Thanks! – marcantonio Apr 21 '15 at 18:18