Update tech_docs/go_getting_started.md

This commit is contained in:
2024-06-18 18:33:15 +00:00
parent f4d8c57963
commit 94eb8d72ff

View File

@@ -1,3 +1,405 @@
# Go (Golang) Comprehensive Guide
## Table of Contents
1. Introduction to Go Structs
- Defining a Struct
- Creating Instances
- Accessing and Modifying Fields
- Embedding Structs
- Methods on Structs
- JSON Encoding/Decoding
2. Project Structure and Best Practices
- Entry Points
- Project Structure
- Explanation of Directories
- Best Practices
- Example Project
## 1. Introduction to Go Structs
### Defining a Struct
A struct in Go is a composite data type that groups together variables under a single name. It is defined using the `type` and `struct` keywords.
```go
package main
import "fmt"
// Define a struct type called Person
type Person struct {
Name string
Age int
City string
}
func main() {
// Creating an instance of the Person struct
p := Person{Name: "Alice", Age: 30, City: "New York"}
// Accessing and modifying struct fields
fmt.Println("Name:", p.Name)
fmt.Println("Age:", p.Age)
fmt.Println("City:", p.City)
}
```
### Creating Instances
You can create instances of a struct using several methods:
- Using a struct literal:
```go
p := Person{Name: "Alice", Age: 30, City: "New York"}
```
- Creating an instance with zero values and then setting fields:
```go
var p Person
p.Name = "Bob"
p.Age = 25
p.City = "San Francisco"
```
- Using the `new` keyword (returns a pointer to the struct):
```go
p := new(Person)
p.Name = "Charlie"
p.Age = 28
p.City = "Los Angeles"
```
### Accessing and Modifying Fields
Access struct fields using the dot notation:
```go
p := Person{Name: "Alice", Age: 30, City: "New York"}
// Access fields
fmt.Println(p.Name) // Output: Alice
// Modify fields
p.Age = 31
fmt.Println(p.Age) // Output: 31
```
### Embedding Structs
Go supports embedding structs within other structs to create more complex data structures.
```go
type Address struct {
City string
State string
ZipCode string
}
type Person struct {
Name string
Age int
Address // Embedding Address struct
}
func main() {
p := Person{
Name: "Alice",
Age: 30,
Address: Address{
City: "New York",
State: "NY",
ZipCode: "10001",
},
}
fmt.Println(p.Name) // Output: Alice
fmt.Println(p.Address.City) // Output: New York
}
```
### Methods on Structs
You can define methods on structs, which are functions with a receiver argument.
```go
type Person struct {
Name string
Age int
}
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}
func main() {
p := Person{Name: "Alice", Age: 30}
p.Greet() // Output: Hello, my name is Alice and I am 30 years old.
}
```
### JSON Encoding/Decoding
Gos standard library includes support for JSON encoding and decoding, which works seamlessly with structs.
```go
package main
import (
"encoding/json"
"fmt"
)
type Person struct {
Name string
Age int
City string
}
func main() {
p := Person{Name: "Alice", Age: 30, City: "New York"}
// Encode to JSON
jsonData, err := json.Marshal(p)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(string(jsonData)) // Output: {"Name":"Alice","Age":30,"City":"New York"}
// Decode from JSON
jsonStr := `{"Name":"Bob","Age":25,"City":"San Francisco"}`
var p2 Person
err = json.Unmarshal([]byte(jsonStr), &p2)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(p2) // Output: {Bob 25 San Francisco}
}
```
## 2. Project Structure and Best Practices
### Entry Points
The entry point of a Go application is the `main` package, which contains a `main` function. This is where the execution of your application begins.
```go
// main.go
package main
import "fmt"
func main() {
fmt.Println("Hello, World!")
}
```
### Project Structure
A typical Go project structure looks like this:
```
myproject/
├── cmd/
│ └── myapp/
│ └── main.go
├── pkg/
│ └── mypackage/
│ └── mypackage.go
├── internal/
│ └── myinternalpackage/
│ └── myinternalpackage.go
├── api/
│ └── handlers.go
├── web/
│ ├── templates/
│ └── static/
├── configs/
│ └── config.yaml
├── scripts/
│ └── build.sh
├── test/
│ └── integration_test.go
├── go.mod
└── README.md
```
### Explanation of Directories
- **cmd/**: Contains the entry points of the applications. Each subdirectory under `cmd` represents a separate application. This is useful for projects with multiple binaries.
```go
// cmd/myapp/main.go
package main
import "myproject/pkg/mypackage"
func main() {
mypackage.DoSomething()
}
```
- **pkg/**: Contains library code that can be imported by other projects and applications. It is reusable and shared across different parts of the project.
```go
// pkg/mypackage/mypackage.go
package mypackage
import "fmt"
func DoSomething() {
fmt.Println("Doing something!")
}
```
- **internal/**: Similar to `pkg`, but the code here is only used internally by your project. It cannot be imported by other projects.
```go
// internal/myinternalpackage/myinternalpackage.go
package myinternalpackage
import "fmt"
func InternalFunction() {
fmt.Println("Internal function")
}
```
- **api/**: Contains code related to your API, such as handlers, routes, and middleware.
```go
// api/handlers.go
package api
import (
"net/http"
"fmt"
)
func HelloHandler(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Hello, World!")
}
```
- **web/**: Contains web-related resources like HTML templates, CSS, and JavaScript files.
- **configs/**: Stores configuration files, such as YAML, JSON, or TOML files.
- **scripts/**: Contains scripts for tasks like building, deploying, and running the project.
- **test/**: Houses test files, such as integration tests or end-to-end tests.
- **go.mod**: The Go module file, which defines the module path and dependencies.
```go
module myproject
go 1.18
require (
github.com/gorilla/mux v1.8.0
)
```
### Best Practices
- **Use Modules**: Always use Go modules (`go.mod`) to manage dependencies.
- **Consistent Naming**: Use consistent naming conventions for packages and files.
- **Small Packages**: Keep packages small and focused on a single responsibility.
- **Documentation**: Write documentation for your packages and functions using GoDoc comments.
- **Testing**: Write tests for your code using the `testing` package. Place unit tests in the same package with a `_test.go` suffix.
```go
// pkg/mypackage/mypackage_test.go
package mypackage
import "testing"
func TestDoSomething(t *testing.T) {
// Test code
}
```
- **Version Control**: Use a version control system like Git. Keep your `go.mod` and `go.sum` files updated.
- **CI/CD**: Integrate Continuous Integration and Continuous Deployment pipelines to automate testing and deployment.
### Example Project
Heres a simple example project to demonstrate the structure:
```
simpleapp/
├── cmd/
│ └── simpleapp/
│ └── main.go
├── pkg/
│ └── greeter/
│ └── greeter.go
├── internal/
│ └── util/
│ └── util.go
├── go.mod
└── README.md
```
**go.mod:**
```go
module simpleapp
go 1.18
```
**cmd/simpleapp/main.go:**
```go
package main
import (
"fmt"
"simpleapp/pkg/greeter"
)
func main() {
fmt.Println(greeter.Greet("World"))
}
```
**pkg/greeter/greeter.go:**
```go
package greeter
import "fmt"
func Greet(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
```
**internal/util/util.go:**
```go
package util
import "strings"
func ToUpper(s string) string {
return strings.ToUpper(s)
}
```
With this structure, your Go projects will be organized, maintainable, and scalable.
---
# Golang Guide
## Introduction to Golang