این جزوه به بررسی جنبههای پیشرفته برنامهنویسی در Go میپردازد و شامل موضوعات زیر است:
هر بخش با توضیحات مفهومی، مثالهای عملی، نکات پیشرفته، و بهترین شیوهها همراه است.
بستهها (Packages) در Go واحدهای سازماندهی کد هستند که امکان استفاده مجدد و ماژولاریتی را فراهم میکنند. ماژولها (Modules) ساختار مدرنتری برای مدیریت پروژهها و وابستگیها ارائه میدهند.
یک بسته مجموعهای از فایلهای Go است که در یک دایرکتوری قرار دارند و نام بسته در ابتدای هر فایل مشخص میشود (معمولاً نام دایرکتوری).
mkdir mypackage
cd mypackage
touch mypackage.go
// mypackage/mypackage.go
package mypackage
import "fmt"
// Hello یک تابع عمومی است (با حرف بزرگ شروع میشود)
func Hello(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
// تابع خصوصی (با حرف کوچک شروع میشود)
func secret() string {
return "This is private"
}
// main.go
package main
import (
"example.com/mypackage"
"fmt"
)
func main() {
fmt.Println(mypackage.Hello("Ali")) // خروجی: Hello, Ali!
}
Hello
) عمومی هستند؛ با حرف کوچک (مثل secret
) خصوصیاند. go mod init example.com/myapp
Go از مستندات درونخطی پشتیبانی میکند که با ابزار godoc
قابل مشاهده است.
// mypackage/mypackage.go
package mypackage
// Hello یک پیام خوشآمدگویی برای نام دادهشده تولید میکند.
func Hello(name string) string {
return fmt.Sprintf("Hello, %s!", name)
}
go doc example.com/mypackage
یا سرور مستندات:
godoc -http=:6060
سپس به http://localhost:6060/pkg/example.com/mypackage
بروید.
// Example
استفاده کنید:
// ExampleHello یک نمونه از استفاده تابع Hello است.
func ExampleHello() {
fmt.Println(Hello("Ali"))
// Output: Hello, Ali!
}
github.com/username/mypackage
.git tag v1.0.0
git push origin v1.0.0
go.mod
را تنظیم کنید:
module github.com/username/mypackage
go 1.20
go get github.com/username/mypackage@v1.0.0
vX.Y.Z
استفاده کنید.internal
و زیرماژولها ایجاد کنید.pkg.go.dev
برای نمایش خودکار مستندات استفاده کنید.no matching versions
میشود.go.mod
و مسیر مخزن.Go از سیستم ماژولها برای مدیریت وابستگیها استفاده میکند که با go mod
کنترل میشود.
go mod init example.com/myapp
این دستور فایل go.mod
را ایجاد میکند:
module example.com/myapp
go 1.20
برای استفاده از یک بسته خارجی:
go get github.com/some/package@v1.2.3
این کار وابستگی را به go.mod
اضافه میکند:
require github.com/some/package v1.2.3
go get -u github.com/some/package
go mod tidy
Vendoring کپی کدهای وابستگیها را در پروژه ذخیره میکند تا بدون دسترسی به اینترنت قابل ساخت باشد.
go mod vendor
این کار دایرکتوری vendor
را ایجاد میکند.
go build -mod=vendor
go mod
بهینهتر است.vX.Y.Z
.require github.com/some/package v1.2.0
go get github.com/some/package@v1.2.3
replace github.com/some/package => ../local/package
GOPROXY
برای دانلود سریعتر استفاده کنید:
export GOPROXY=https://proxy.golang.org
go.mod
با go mod tidy
.کتابخانه استاندارد Go شامل پکیجهای قدرتمندی است که برای کارهای روزمره استفاده میشوند.
برای فرمتدهی و چاپ استفاده میشود.
fmt.Println("Hello") // چاپ ساده
fmt.Printf("Name: %s, Age: %d\n", "Ali", 30) // فرمتدهی
var name string
fmt.Scan(&name)
برای عملیات روی رشتهها:
s := "Hello, World"
fmt.Println(strings.Contains(s, "World")) // true
fmt.Println(strings.ReplaceAll(s, "World", "Go")) // Hello, Go
برای کار با زمان و تاریخ:
now := time.Now()
fmt.Println(now) // 2025-05-17 16:53:00 +0000 UTC
time.Sleep(2 * time.Second)
fmt.Println(now.Format("2006-01-02")) // 2025-05-17
برای عملیات ریاضی:
fmt.Println(math.Sqrt(16)) // 4
fmt.Println(math.Pow(2, 3)) // 8
fmt.Println(math.Pi) // 3.141592653589793
package main
import (
"fmt"
"math"
"strings"
"time"
)
func main() {
name := "Ali"
fmt.Printf("Hello, %s!\n", strings.ToUpper(name))
t := time.Now()
fmt.Println("Current time:", t.Format("2006-01-02 15:04"))
fmt.Println("Square root of 16:", math.Sqrt(16))
}
strings.Builder
به جای strings.Replace
برای تغییرات مکرر استفاده کنید.time.Since
استفاده کنید:
start := time.Now()
// عملیات
fmt.Println(time.Since(start))
2006-01-02
استفاده شود).fmt.Scan
بدون مدیریت خطا.Go از فرمتهای داده مانند JSON، YAML، و XML پشتیبانی میکند.
type Person struct {
Name string `json:"name"`
Age int `json:"age"`
}
p := Person{Name: "Ali", Age: 30}
data, err := json.Marshal(p)
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data)) // {"name":"Ali","age":30}
jsonStr := `{"name":"Ali","age":30}`
var p Person
err := json.Unmarshal([]byte(jsonStr), &p)
if err != nil {
log.Fatal(err)
}
fmt.Println(p) // {Ali 30}
json
برای کنترل نام فیلدها و رفتار (مثل omitempty
) استفاده میشوند:
type Person struct {
Name string `json:"name,omitempty"`
Age int `json:"age"`
}
map[string]interface{}
یا []interface{}
استفاده کنید.برای YAML نیاز به بسته خارجی (مثل gopkg.in/yaml.v3
) دارید:
go get gopkg.in/yaml.v3
type Config struct {
Name string `yaml:"name"`
Age int `yaml:"age"`
}
yamlStr := "name: Ali\nage: 30"
var c Config
err := yaml.Unmarshal([]byte(yamlStr), &c)
if err != nil {
log.Fatal(err)
}
fmt.Println(c) // {Ali 30}
مشابه JSON، با پکیج encoding/xml
:
type Person struct {
XMLName xml.Name `xml:"person"`
Name string `xml:"name"`
Age int `xml:"age"`
}
xmlStr := `<person><name>Ali</name><age>30</age></person>`
var p Person
err := xml.Unmarshal([]byte(xmlStr), &p)
fmt.Println(p) // {Ali 30}
json.Decoder
و xml.Decoder
استفاده کنید:
dec := json.NewDecoder(strings.NewReader(jsonStr))
var p Person
dec.Decode(&p)
Go ابزارهای قدرتمندی برای کار با فایلها و عملیات ورودی/خروجی ارائه میدهد.
data := []byte("Hello, Go!")
err := os.WriteFile("output.txt", data, 0644)
if err != nil {
log.Fatal(err)
}
data, err := os.ReadFile("output.txt")
if err != nil {
log.Fatal(err)
}
fmt.Println(string(data)) // Hello, Go!
err := os.Mkdir("mydir", 0755)
entries, err := os.ReadDir("mydir")
for _, entry := range entries {
fmt.Println(entry.Name())
}
برای بهبود کارایی از bufio
استفاده کنید:
file, err := os.Open("input.txt")
if err != nil {
log.Fatal(err)
}
defer file.Close()
scanner := bufio.NewScanner(file)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
file, err := os.Create("output.txt")
writer := bufio.NewWriter(file)
writer.WriteString("Hello, Go!")
writer.Flush() // اطمینان از نوشتن
defer file.Close()
استفاده کنید.io.Reader
و io.Writer
استفاده کنید.Go ابزارهای داخلی قدرتمندی برای تستنویسی ارائه میدهد.
// math.go
package math
func Add(a, b int) int {
return a + b
}
// math_test.go
package math
import "testing"
func TestAdd(t *testing.T) {
result := Add(2, 3)
if result != 5 {
t.Errorf("Add(2, 3) = %d; want 5", result)
}
}
go test
برای تست چندین سناریو:
func TestAdd(t *testing.T) {
tests := []struct {
a, b, want int
}{
{2, 3, 5},
{0, 0, 0},
{-1, 1, 0},
}
for _, tt := range tests {
t.Run(fmt.Sprintf("%d+%d", tt.a, tt.b), func(t *testing.T) {
if got := Add(tt.a, tt.b); got != tt.want {
t.Errorf("Add(%d, %d) = %d; want %d", tt.a, tt.b, got, tt.want)
}
})
}
}
برای اندازهگیری عملکرد:
func BenchmarkAdd(b *testing.B) {
for i := 0; i < b.N; i++ {
Add(2, 3)
}
}
اجرا:
go test -bench=.
testify
برای mock استفاده کنید:
go get github.com/stretchr/testify
go test -cover
sync.WaitGroup
برای هماهنگی استفاده کنید.api
, db
, utils
).go mod tidy
را اجرا کنید.این جزوه تمام جنبههای برنامهنویسی پیشرفته در Go را با جزئیات کامل پوشش داد. از ایجاد بستهها و مدیریت وابستگیها تا کار با فرمتهای داده، فایلها، و تستنویسی، هر بخش با مثالهای عملی و نکات پیشرفته ارائه شد. برای یادگیری عمیقتر:
https://golang.org/doc/