Folder name = package name = module name

Hi forum,

I found the documents on “folder name”, “package name” and “module name” a bit confused to me. This is what I understood. Please correct me if I was wrong.

These plus workspace thing are much more complicated than module and package in Python.

Thanks!

  1. folder name = package name = module name .
    though the document does not say so, the three always match: folder name, package name, and module name (last part).
  folder name :                  ./greetings
  package name:            package greetings
  module name : module example.com/greetings
  1. main package keep its name, the two of the rest still match.

  2. import “name” and go mod init “name”, they are the same.

  import              "example.com/greetings"
  go mod init         "example.com/greetings"
  1. sub-package in sub-dir needs one more level
  import              "example.com/hello/morestrings"
  1. one folder = one package = one module .
    but sub-package in sub-dir does not need to run go mod init command.
$ pwd
/Users/ljh/Documents/work
$
$ find . -print | sed -e 's;[^/]*/;|____;g;s;____|; |;g' 
.
|____greetings
| |____go.mod
| |____greetings.go
|____hello
| |____morestrings
| | |____reverse.go
| |____go.mod
| |____hello.go
$ 
$ 
$ cat greetings/go.mod 
module example.com/greetings
go 1.18
$ 
$ 
$ cat greetings/greetings.go 
// https://golang.google.cn/doc/tutorial/create-module
package greetings
import "fmt"
func Hello(name string) string {
    message := fmt.Sprintf("Hi, %v. Welcome!", name)
    return message
}
$ 
$ 
$ cat hello/go.mod 
module example.com/hello
go 1.18
replace example.com/greetings => ../greetings
require example.com/greetings v0.0.0-00010101000000-000000000000
$ 
$   
$ cat hello/hello.go 
// https://golang.google.cn/doc/tutorial/call-module-code
package main
import (
    "fmt"
    "example.com/greetings"
    "example.com/hello/morestrings"
)
func main() {
    message := greetings.Hello("Gladys")
    fmt.Println(message)
    fmt.Println(morestrings.ReverseRunes("!oG ,olleH"))
}
$ 
$ 
$ cat hello/morestrings/reverse.go 
// https://golang.google.cn/doc/code
package morestrings
func ReverseRunes(s string) string {
    r := []rune(s)
    for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
        r[i], r[j] = r[j], r[i]
    }
    return string(r)
}
$ 

The code in the modules builds correctly. The extension golang.go v0.32.0 shows error message in VSCode. Seems even the extension can not understand the complex module, package and workspace things.

Error loading workspace: You are outside of a module and outside of $GOPATH/src. If you are using modules, please open your editor to a directory in your module.

Your editors workspace root does not contain a go.mod, so it doesn’t see a module.

To roughly answer your questions, at least as much as I understand them:

  1. A module is the location where you find the sources and the module description, aka go.mod. The module is also a package and each package can contain subpackages, which are organised in a tree like manor. The foldernames are used for import, while the package name is used as qualifier in the code. Given a module example.com/foo/bar with a package quux would be accessible using quux in the importing file. package and folder name should only diverge if you have good reasons for it.
  2. Not sure what you mean by “keep its name”
  3. They are not. As there can (and usually are) be sub packages in the top level module.
  4. Of cours, subfolders are subfolders, so you need to nest them. It is not any different on your local filesystem
  5. One folder is one package (+ tests), but a module can have many folders and therefore subpackages. And go mod init creates a module, not a package, therefore you do not need to run it for subpackages. And you do not even need it for a module. In theory, you could create the bare go.mod on your own. Minimal content is module declaration followed by the go directive IIRC.
3 Likes

Thanks Norbert,

I did not use go work init command. It is ok now.

I still have some confusion.

  1. All source files in a folder use the same package name, right? For example, in a folder: hello, two files: a.go, b.go, should both use the name “hello” for the package directive:
package hello
  1. A package consists of all the source files in a folder use the same name for package directory, is it correct?

  2. Should the name in package directive be as same as the folder name?

Not “should have”, but “must have”, the compiler will error if there are different packages in the same folder (_test suffix is allowed)

yes.

As I said, yes, unless you have a very good reason to make them different.

2 Likes

Thanks Norbert,

I just find it in the spec

A set of files sharing the same PackageName form the implementation of a package. An implementation may require that all source files for a package inhabit the same directory.

If, in a folder, there are different names occur in package declarations from source files, it will not build and show a message:

... found packages ...

And I did a test. Actually, folder, package and module name can be different. Module name is used in go mod init command, and import declaration.

If folder name is different from module name, it will need go mod edit - replace example.com/module_name=../folder_name.

If package name is different from module name, the exported name are still referenced in the same way: package_name.Hello(). While the import declaration look like import "module_name". It is just not easy to find out which module the package and exported name belong to.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.