modules-go

path: courses/go-course/modules-go.md

- **fileName**: modules-go
- **Created on**: 2024-09-02 11:28:07

Modules

Go programs are organized into packages. A package is a directory of Go code that's all compiled together. Functions, types, variables, and constants defined in one source file are visible to all other source files within the same package (directory).
A repository contains one or more modules. A module is a collection of Go packages that are released together.

One module per repo (usually)

A file named go.mod at the root of a project declares the module. It contains:
The module path
The version of the Go language your project requires
Optionally, any external package dependencies your project has

command in go

Command Description
go run Compile and run a Go program
go build Compile the Go program and create an executable binary
go install Compile and install the Go program
go test Run tests in the current package
go fmt Format Go source code
go get Download and install packages
go mod Manage module dependencies
go list List Go packages
go version Display the Go version
go env Print Go environment information
go clean Remove object files and cached files
go vet Analyze Go source code for potential errors
go build -o Specify the output file name for the compiled binary
go run <file> Run a specific Go source file
go doc Show documentation for a package or symbol
go generate Run Go generate commands to produce Go code
go test -v Run tests with verbose output
go test -cover Show test coverage information
go tool Access Go tools (e.g., go tool pprof)
go clean -testcache Remove the test cache
go list -m List module dependencies
go mod tidy Add or remove modules based on the imports
go mod vendor Copy modules into the vendor directory
go mod verify Verify that dependencies have expected content
go run . Run the Go program in the current directory

now let's talk about packages and import and export

// go.mod file
module github.com/yossefsabry/go-course // the name for the package 

go 1.23.0 // version go

replace github.com/yossefsabry/mystrings v0.0.0 => ../mystrings // replace used for get the packages localy from the device

require (
    github.com/yossefsabry/mystrings v0.0.0 // the dependence for the package 
)

/*
	now how to works if there no replace keyword the package gone get the the dependenace from github.com{any place like gitlab or else no problem} using the command `go get github.com/yossefsabry/go-course` and then run the packages if the package is not exists show panic error now i using the replace keyword to replace the github.com with local packages to use
*/

Clean Packages

I’ve often seen, and have been responsible for, throwing code into packages without much thought. I’ve quickly drawn a line in the sand and started putting code into different directories (which in Go are different packages by definition) just for the sake of organization. Learning to properly build small and reusable packages can take your Go career to the next level.

Rules Of Thumb

  1. Hide internal logic
    If you're familiar with the pillars of OOP, this is a practice in encapsulation.

Oftentimes an application will have complex logic that requires a lot of code. In almost every case the logic that the application cares about can be exposed via an API, and most of the dirty work can be kept within a package. For example, imagine we are building an application that needs to classify images. We could build a package:

package classifier

// ClassifyImage classifies images as "hotdog" or "not hotdog"
func ClassifyImage(image []byte) (imageType string) {
	if hasHotdogColors(image) && hasHotdogShape(image) {
		return "hotdog"
	} else {
		return "not hotdog"
	}
}

func hasHotdogShape(image []byte) bool {
	// internal logic that the application doesn't need to know about
	return true
}

func hasHotdogColors(image []byte) bool {
	// internal logic that the application doesn't need to know about
	return true
}

We create an API by only exposing the function(s) that the application-level needs to know about. All other logic is unexported to keep a clean separation of concerns. The application doesn’t need to know how to classify an image, just the result of the classification.

  1. Don’t change APIs
    The unexported functions within a package can and should change often for testing, refactoring, and bug fixing.

A well-designed library will have a stable API so that users don't get breaking changes each time they update the package version. In Go, this means not changing exported function’s signatures.

  1. Don’t export functions from the main package
    A main package isn't a library, there's no need to export functions from it.

  2. Packages shouldn't know about dependents
    Perhaps one of the most important and most broken rules is that a package shouldn’t know anything about its dependents. In other words, a package should never have specific knowledge about a particular application that uses it.

continue:[[]]
before:pointer-go.md