On Saturday, 19 November 2022 at 02:50:18 UTC pat2...@gmail.com wrote: > On Friday, November 18, 2022 at 1:10:40 PM UTC-5 Brian Candler wrote: > >> You still should have a go.mod. Even if you don't intend to publish your >> code anywhere, you give it a module name - anything will do as long as it >> meets the syntax requirements. >> > > OK, I can have a go.mod > But don''t I need to have a "package main" in order to get an executable? >
Correct. Your .go source file(s), which together build a single executable, will all have "package main" as the first line, and all sit in the same directory. Starting point, with a single file: mkdir hello cd hello go mod init example.com/hello # this creates "go.mod" vi hello.go # create your program here go run . where hello.go contains package main import "fmt" func main() { fmt.Println("Hello, world!") } You could then split this into two files: -- hello.go -- package main func main() { sayHello() } -- speaker.go -- package main import "fmt" func sayHello() { fmt.Println("Hello, world!") } In general, all source files in the same directory are part of the same package, and must have the same 'package' declaration. The exception is if you choose to put your test functions in a different package (if you want them only to be able to access the public API of your package) You can have multiple .go source files, in the same directory, all part of the same package. Functions in each file can use functions and data from any other file, without having to refer to them explicitly. Think of "a directory of files" as a single compilation unit. It's pretty much the same as having one big source file, except that each individual source file still has to have its own 'import' statements. > > If you need to split your code into other packages, you can put those in >> subdirectories. Those don't need their own go.mod files. The path for >> each package is the path from the outer go.mod file, concatenated with the >> subdirectory. >> > > Sure, once there is more than 25 lines of source code, subdirectories make > sense. > But you don't need to split into multiple subdirectories at this point: only multiple files in the same directory. (Unless you're talking about separate executables, in which case, yes they need to be in separate subdirectories). > > Do I really need to have the source code deeply burried in names that tie > it all to my github repository? > I'm not sure what you mean by that. All the source files in the same package (in the same directory) don't need to import each other at all, so they do not reference each other by module name. The module name is used when you need to import code from somewhere else. If you choose a module name that links to your github repository, then other people will be able to import your module using that name, and the code will be fetched and built automatically. > I'm using > ~/sandbox/gows/src/github.com/pfarrell51/cmd > > because "gows" is "go work space" with src code > Be careful with your terminology here: there is a specific feature called "go workspaces <https://go.dev/doc/tutorial/workspaces>", but this has only been recently added and is an advanced topic (for working on very large projects) and you should ignore it for now. If you just mean "this is where I put my source files", then that's fine; but all the files in one directory must be part of the same package, and thus part of the same application (i.e. you build them all as one executable). Incidentally, there is no need to have github.com in the directory path on your local filesystem. You could just use ~/projects/cmd What if you are building multiple executables? You put them into separate subdirectories. If you're treating this all as one module: ~/projects/cmd contains go.mod (and nothing else) ~/projects/cmd/foo contains *.go files, all for package main, which build the "foo" executable ~/projects/cmd/bar contains *.go files, all for package main, which build the "bar" executable You can then if you wish publish this whole lot in a single repo as github.com/pfarrell51/cmd - or not, as you choose. If not, then the name that you choose for your module doesn't matter. This repo can also contain library code which is shared between these executables - this would be in separate packages, and would have to be explicitly imported by the executables. Option 1: the top-level ~/projects/cmd can contain *.go files. These might all have "package cmd" and can be imported using your bare module path, e.g. github.com/pfarrell51/cmd Option 2: you can put library code in subdirectories too, e.g. ~/projects/cmd/utils/ can contain *.go files, with "package utils", and are imported using github.com/pfarrell51/cmd/utils. There is a special subdirectory "internal" which can be used for code which is shared between your own executables but you *don't* want to be available to anyone else importing from your repo. So your foo and bar executables might look like this: package main import "github.com/pfarrell51/cmd" func main() { cmd.SayHello() } If the "foo" and "bar" executables are completely independent and don't share any code, then I would publish them as separate repos, each with their own go.mod. Note that import "github.com/pfarrell51/cmd" doesn't mean "fetch this code from github". It just refers to the module's name. By walking up the parent directories and finding go.mod, Go realises that the named module you are referring to is already on your filesystem as part of your project, and uses that directly. This is why it works to use random module names like example.com/test Regards, Brian. P.S. I don't want to confuse you any further, but you should be aware that package name that you use (for a bundle of sources files in a directory) doesn't necessarily have to be the same as the subdirectory they are contained within - but if they don't match it can get confusing. For example: -- go.mod -- module example.com/myprog go 1.16 -- start.go -- package main import ( "example.com/myprog/foo" "fmt" ) func main() { fmt.Println(wibble.Bibble()) } -- foo/misc.go -- package wibble func Bibble() string { return "baa" } The subdirectory "foo" contains a package "wibble". So in the main program (start.go), there is import "example.com/myprog/foo", but it actually makes a package called "wibble" available. The solution here is to name the imported package explicitly, e.g. import ( wibble "example.com/myprog/foo" ) This says "regardless of what the imported package calls itself, I want to refer to it as "wibble" within this package" -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/a80a266a-e060-4e9f-ba85-7bcc7236068bn%40googlegroups.com.