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.

Reply via email to