Приведите примеры использования метода `Add` в стандартной библиотеке Go и объясните его назначение.

Ответ

Метод Add не является встроенной конструкцией языка, а представляет собой конвенциональное имя для методов в различных пакетах стандартной библиотеки. Его основная задача — "добавлять" что-либо к объекту. Рассмотрим наиболее частые примеры.

1. sync.WaitGroup

В sync.WaitGroup метод Add(delta int) увеличивает (или уменьшает, если delta отрицательна) внутренний счетчик горутин, завершения которых нужно дождаться.

  • wg.Add(1): Увеличить счетчик перед запуском горутины.
  • wg.Done(): Уменьшить счетчик (эквивалентно wg.Add(-1)), обычно вызывается в конце горутины через defer.
  • wg.Wait(): Блокирует выполнение до тех пор, пока счетчик не станет равен нулю.
package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    var wg sync.WaitGroup
    for i := 1; i <= 3; i++ {
        wg.Add(1) // Сообщаем, что будем ждать еще одну горутину
        go func(id int) {
            defer wg.Done() // Сообщаем о завершении
            fmt.Printf("Горутина %d работает...n", id)
            time.Sleep(time.Second)
        }(i)
    }

wf.Wait() // Ждем, пока счетчик не обнулится
    fmt.Println("Все горутины завершены.")
}

2. time.Time

В time.Time метод Add(d Duration) возвращает новый объект time.Time, сдвинутый на указанный промежуток времени d.

package main

import (
    "fmt"
    "time"
)

func main() {
    now := time.Now()
    fmt.Println("Сейчас:", now.Format(time.RFC3339))

    // Добавляем 2 часа и 30 минут
    future := now.Add(2*time.Hour + 30*time.Minute)
    fmt.Println("Через 2.5 часа:", future.Format(time.RFC3339))
}

3. math/big.Int

В пакете math/big метод Add(x, y *Int) используется для сложения больших чисел, которые не помещаются в стандартные типы (int64, uint64). Он вычисляет сумму x + y и сохраняет результат в ресивере z (z.Add(x, y)).

package main

import (
    "fmt"
    "math/big"
)

func main() {
    x := new(big.Int)
    x.SetString("10000000000000000000", 10) // 10^19

    y := new(big.Int)
    y.SetString("20000000000000000000", 10) // 2 * 10^19

    sum := new(big.Int)
    sum.Add(x, y)

    fmt.Printf("Сумма: %sn", sum.String()) // Сумма: 30000000000000000000
}