Can't understand how to compile go code in multiple files [duplicate] - go

This question already has answers here:
Organizing a multiple-file Go project [closed]
(7 answers)
Closed 9 years ago.
OK, Go's major selling point is its ease of compilation and wonderful toolchain, but as a go newbie I'm really lost there and can't understand the documentation on that point.
I have a stack toy example within two files (one for the type definition and methods, called stack.go, one for the main program, called main.go), both are in my GOPATH/src/stacker directory.
How should each file be named ? Does it have any importance at all ? Is there at least a convention ? A mandatory naming ?
What should be the package name ? I understood they should use the same package name, but which one ? Is it stacker ?
In main.go, how should I use the import directive to import stack.go ?
I have tried many combinations, none working until now.

You can name the files however you like, just beware of special suffixes like _test and _<arch> (_darwin, _unix, etc.). Also note that files prefixed with . or _ won't be compiled into the package!
It is recommended that you name the package like the folder the file is in, although it's possible (but confusing) to name a package differently in the declaration package mypkg
If stack.go is in the same folder/package as main.go, you don't need to import. Everything delcared in stack.go is already available in main.go, because it is in the same package.
If stacker should compile into an executable, you should use package main.

Related

Does the go compiler compile the package that's never used in main [duplicate]

This question already has answers here:
How to remove unused code at compile time?
(2 answers)
Splitting client/server code
(1 answer)
Closed last month.
If I have a go module that has three package like A, B, C. In the main.go and all of its import, only A, B packages are ever used. My question is, does the binary produced by go build has any code from package C?
The binary build will only include the transitive closure of all symbols referenced from main. This will include only those functions and data from the imported packages, and all the methods of types that are used. So if you have a function in a package that is never used, that will not be in the binary. However if you use a data type with unused methods, those methods will be in the binary.

relationship between directory structure and packages in golang

I am new to Golang and grasp the concept of packages fairly well, but have a question about their relationship to folder/directory location.
So I am working on a fairly large project with multiple subdirectories inside the /pkg directory. There are probably 30+ distinct package ___ namespaces declared.
Typically of course all files inside of a directory will have the same package, e.g. /pkg/system/api-client; all files in that directory are declared package apiclient
The question arises when I notice two files of package config; one is in /pkg/config/config.go and the other is /pkg/writer-job/pkg/config/config.go.
Are they part of the same package? If so, what is the convention for this (as it seems quite scattered)? And if not, how do you lexically separate config as two separate packages? I did search the docs but don't see this.
There are two concepts: package name, and import path.
The package name is what you declare with a package as the first statement in a go file. A directory can contain at most one package.
An import path is how you import that package, and shows the location of the package. Once you import it, the declared package name is used to qualify exported identifiers from that package.
In case of conflicting package names, you define an alias for one of them.
import (
"someproject/pkg/config"
writerconfig "someproject/pkg/writer-job/config"
)
Then, config.X refers to the first package, and writerconfig.X refers to the second.

Can I develop a go package in multiple source directories?

I am developing a go package, which is a little bit complex and thus I want to organize the source code into multiple directories.
However, I don't want the users of the package to have to use too long imports. Anyways, the internal structure of the package isn't their concern.
Thus, my package structure looks so:
subDir1
subSubDir1
subSubDir2
subDir2
subSubDir3
...and so on. All of them have their exported calls.
I would like to avoid that my users have to import
import (
"mypackage/subDir1"
"mypackage/subDir1/subSubDir2"
)
...and so on.
I only want, if they want to use an exported function from my package, they should have access all of them by simply importing mypackage.
I tried that I declare package mypackage in all of the .go files. Thus, I had source files in different directories, but with the same package declaration.
In this case, the problem what I've confronted was that I simply couldn't import multiple directories from the same package. It said:
./src1.go:6:15: error: redefinition of ‘mypackage’
"mypackage/mysubdir1"
^
./src1.go:4:10: note: previous definition of ‘mypackage’ was here
"mypackage"
^
./src1.go:5:15: error: redefinition of ‘mypackage’
"mypackage/mysubdir2"
^
./src1.go:4:10: note: previous definition of ‘mypackage’ was here
"mypackage"
^
Is it somehow possible?
You should not do this in any case, as the language spec allows a compiler implementation to reject such constructs. Quoting from Spec: Package clause:
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.
Instead "structure" your file names to mimic the folder structure; e.g. instead of files of
foo/foo1.go
foo/bar/bar1.go
foo/bar/bar2.go
You could simply use:
foo/foo1.go
foo/bar-bar1.go
foo/bar-bar2.go
Also if your package is so big that you would need multiple folders to even "host" the files of the package implementation, you should really consider not implementing it as a single package, but break it into multiple packages.
Also note that Go 1.5 introduced internal packages. If you create a special internal subfolder inside your package folder, you may create any number of subpackages inside that (even using multiple levels). Your package will be able to import and use them (or to be more precise all packages rooted at your package folder), but no one else outside will be able to do so, it would be a compile time error.
E.g. you may create a foo package, have a foo/foo.go file, and foo/internal/bar package. foo will be able to import foo/internal/bar, but e.g. boo won't. Also foo/baz will also be able to import and use foo/internal/bar because it's rooted at foo/.
So you may use internal packages to break down your big package into smaller ones, effectively grouping your source files into multiple folders. Only thing you have to pay attention to is to put everything your package wants to export into the package and not into the internal packages (as those are not importable / visible from the "outside").
Inside your package source code, you have to differentiate your source directories by renamed imports. You can declare the same package mypackage in all of your source files (even if they are in different directories).
However, while you import them, you should give an induvidual names to the directories. In your source src1.go, import the other directories on this way:
import (
"mypackage"
submodule1 "mypackage/mySubDir"
)
And you will be able to reach the API defined in "mypackage" as mypackage.AnyThing(), and the API defined in mySubDir as submodule1.AnyThing().
The external world (i.e. the users of your package) will see all exported entities in myPackage.AnyThing().
Avoid namespace collisions. And use better understable, intuitive naming as in the example.
Yes, this is doable without any problems, just invoke the Go compiler by hand, that is not via the go tool.
But the best advice is: Don't do that. It's ugly and unnecessarily complicated. Just design your package properly.
Addendum (because the real intention of this answer seems to get lost sometimes, maybe because irony is too subtle): Don't do that!! This is an incredible stupid idea! Stop fighting the tools! Everybody will rightfully hate you if you do that! Nobody will understand your code or be able to compile it! Just because something is doable in theory doesn't mean this is a sensible idea in any way. Not even for "learning purpose"! You probably even don't know how to invoke the Go compiler by hand and if you figure it out it will be a major pita.

What is purpose of 'package' keyword when it can be inferred by compiler? [duplicate]

This question already has answers here:
What is the purpose of the package declaration?
(2 answers)
Closed 6 years ago.
All of the Go source files inside directory x have package name x declared on top. I know this is not mandatory but doing otherwise will make things unnecessarily complex. So why the go compiler does not infer the package name from directory name?
This exists in almost many other languages like Java or C# where you are forced to declare what can be easily calculated at compile time.
What is the rationale?
Without package you wouldn't be able to distinguish between main programs and libraries.
Furthermore, according to the language specification, the language does not require a package to be identical with a directory:
An implementation may require that all source files for a package inhabit the same directory.
And in practice some packages have different names than their import paths:
If the PackageName is omitted, it defaults to the identifier specified in the package clause of the imported package.
Consider github.com/google/go-gcm which has package gcm in its files. Projects that use this library will have:
import "github.com/google/go-gcm"
And then call things like this:
res, err := gcm.SendHttp(APIKey, notification)
This is particularly common with - because you can't use it in an identifier.

What is the point of using _ in import in go [duplicate]

This question already has answers here:
What does an underscore in front of an import statement mean?
(5 answers)
Closed 7 years ago.
I have seen a strange syntax in go while importing packages: import _ fmt.
I am aware that import f fmt works like an alias for this package and also I know that _ is used as a variable that should not be cared about.
So no prize for guessing that here I am importing a package that I am not going to use. And in fact it looks like this is what happening here.
What I fail to understand is why this might be helpful. If I use for _, v := range(arr){} I use _ because I have no choice and I need to specify to the compiler that it should not worry about the variable that I will not be using.
But if I do not intend to use a package, I would just omit it (if it might be useful later, I would comment it). But no reason for it to be compiled and added to source code.
So is there any point of using this syntax, or is this just a useless artifact from combining aliasing and unused variables?
It means that you want to import it for the side effects. It's usually used with packages that include an init. Of course you could import it normally, too, but the _ makes it clear that you only wanted the side effects.
Search for "Import for side effect" in Effective Go for discussion.
A very common example is net/http/pprof, which attaches some new handlers to the default mux. Packages like github.com/SlyMarbo/spdy use it in the same way to silently modify the default http client.

Resources