Goku

برنامه‌نویسی پیشرفته در زبان Go

این جزوه به بررسی جنبه‌های پیشرفته برنامه‌نویسی در Go می‌پردازد و شامل موضوعات زیر است:

  1. بسته‌ها و ماژول‌ها
  2. مدیریت وابستگی‌ها
  3. پکیج‌های استاندارد
  4. کار با JSON و فرمت‌های داده
  5. فایل‌ها و I/O
  6. تست‌نویسی

هر بخش با توضیحات مفهومی، مثال‌های عملی، نکات پیشرفته، و بهترین شیوه‌ها همراه است.


1. بسته‌ها و ماژول‌ها

بسته‌ها (Packages) در Go واحدهای سازمان‌دهی کد هستند که امکان استفاده مجدد و ماژولاریتی را فراهم می‌کنند. ماژول‌ها (Modules) ساختار مدرن‌تری برای مدیریت پروژه‌ها و وابستگی‌ها ارائه می‌دهند.

1.1. ایجاد بسته‌های سفارشی

تعریف

یک بسته مجموعه‌ای از فایل‌های Go است که در یک دایرکتوری قرار دارند و نام بسته در ابتدای هر فایل مشخص می‌شود (معمولاً نام دایرکتوری).

مراحل ایجاد

  1. ساختار دایرکتوری:
    mkdir mypackage
    cd mypackage
    touch mypackage.go
    
  2. نوشتن کد بسته:
    // 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"
    }
    
  3. استفاده از بسته:
    // main.go
    package main
    
    import (
        "example.com/mypackage"
        "fmt"
    )
    
    func main() {
        fmt.Println(mypackage.Hello("Ali")) // خروجی: Hello, Ali!
    }
    

نکات

1.2. مستندسازی

مستندات با godoc

Go از مستندات درون‌خطی پشتیبانی می‌کند که با ابزار godoc قابل مشاهده است.

بهترین شیوه‌ها

1.3. انتشار بسته

مراحل

  1. مخزن Git:
    • کد را در یک مخزن عمومی (مثل GitHub) قرار دهید: github.com/username/mypackage.
  2. تگ نسخه:
    git tag v1.0.0
    git push origin v1.0.0
    
  3. ماژول Go:
    • فایل go.mod را تنظیم کنید:
      module github.com/username/mypackage
      go 1.20
      
  4. استفاده توسط دیگران:
    go get github.com/username/mypackage@v1.0.0
    

نکات پیشرفته

خطاهای رایج


2. مدیریت وابستگی‌ها

Go از سیستم ماژول‌ها برای مدیریت وابستگی‌ها استفاده می‌کند که با go mod کنترل می‌شود.

2.1. استفاده از 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

2.2. Vendoring

تعریف

Vendoring کپی کدهای وابستگی‌ها را در پروژه ذخیره می‌کند تا بدون دسترسی به اینترنت قابل ساخت باشد.

فعال‌سازی

go mod vendor

این کار دایرکتوری vendor را ایجاد می‌کند.

ساخت با vendor

go build -mod=vendor

نکات

2.3. نسخه‌بندی

نسخه‌بندی معنایی

مدیریت نسخه‌ها

نکات پیشرفته

خطاهای رایج


3. پکیج‌های استاندارد

کتابخانه استاندارد Go شامل پکیج‌های قدرتمندی است که برای کارهای روزمره استفاده می‌شوند.

3.1. پکیج fmt

برای فرمت‌دهی و چاپ استفاده می‌شود.

3.2. پکیج strings

برای عملیات روی رشته‌ها:

3.3. پکیج time

برای کار با زمان و تاریخ:

3.4. پکیج math

برای عملیات ریاضی:

3.5. مثال ترکیبی

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))
}

نکات پیشرفته

خطاهای رایج


4. کار با JSON و فرمت‌های داده

Go از فرمت‌های داده مانند JSON، YAML، و XML پشتیبانی می‌کند.

4.1. JSON

Marshal/Unmarshal

نکات

4.2. YAML

برای YAML نیاز به بسته خارجی (مثل gopkg.in/yaml.v3) دارید:

go get gopkg.in/yaml.v3

4.3. XML

مشابه 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}

نکات پیشرفته

خطاهای رایج


5. فایل‌ها و I/O

Go ابزارهای قدرتمندی برای کار با فایل‌ها و عملیات ورودی/خروجی ارائه می‌دهد.

5.1. خواندن/نوشتن فایل

نوشتن

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!

5.2. کار با دایرکتوری‌ها

5.3. Buffering

برای بهبود کارایی از bufio استفاده کنید:

نکات پیشرفته

خطاهای رایج


6. تست‌نویسی

Go ابزارهای داخلی قدرتمندی برای تست‌نویسی ارائه می‌دهد.

6.1. استفاده از پکیج testing

6.2. تست‌های جدولی

برای تست چندین سناریو:

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)
            }
        })
    }
}

6.3. بنچمارک

برای اندازه‌گیری عملکرد:

func BenchmarkAdd(b *testing.B) {
    for i := 0; i < b.N; i++ {
        Add(2, 3)
    }
}

اجرا:

go test -bench=.

نکات پیشرفته

خطاهای رایج


7. بهترین شیوه‌ها و نکات


8. نتیجه‌گیری

این جزوه تمام جنبه‌های برنامه‌نویسی پیشرفته در Go را با جزئیات کامل پوشش داد. از ایجاد بسته‌ها و مدیریت وابستگی‌ها تا کار با فرمت‌های داده، فایل‌ها، و تست‌نویسی، هر بخش با مثال‌های عملی و نکات پیشرفته ارائه شد. برای یادگیری عمیق‌تر: