Update tech_docs/go_getting_started.md
This commit is contained in:
@@ -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
|
||||
|
||||
Go’s 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
|
||||
|
||||
Here’s 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
|
||||
|
||||
Reference in New Issue
Block a user