Функции builtin

Описание функций builtin

func append

func append(slice []Type, elems ...Type) []Type

Встроенная функция append добавляет элементы в конец слайса. Если он имеет достаточную емкость, целевой слайс переразбивается, чтобы вместить новые элементы. Если нет, выделяется новый базовый массив. Append возвращает обновленный слайс. Поэтому необходимо сохранить результат append, часто в переменной, содержащей сам слайс:

slice = append(slice, elem1, elem2)
slice = append(slice, anotherSlice...)

В качестве особого случая допустимо добавлять строку к байтовому слайсу, например:

slice = append([]byte(«hello »), «world»...)

func cap

func cap(v Type) int

Встроенная функция cap возвращает емкость v в зависимости от его типа:

  • Массив: количество элементов в v (то же, что len(v)).
  • Указатель на массив: количество элементов в *v (то же, что len(v)).
  • Срез: максимальная длина, которую может достичь срез при повторном разрезании; если v равно nil, cap(v) равно нулю.
  • Канал: емкость буфера канала в единицах элементов; если v равно nil, cap(v) равно нулю.

Для некоторых аргументов, таких как простое массивное выражение, результатом может быть константа. Подробности см. в разделе «Длина и емкость» спецификации языка Go.

func clear

func clear[T ~[]Type | ~map[Type]Type1](t T)

Встроенная функция clear очищает карты и фрагменты.

  • Для карт clear удаляет все записи, в результате чего карта становится пустой.
  • Для слайсов clear устанавливает все элементы до длины слайса в нулевое значение соответствующего типа элемента.

Если тип аргумента является типовым параметром, набор типов типового параметра должен содержать только типы карт или слайсов, и clear выполняет операцию, подразумеваемую типовым аргументом. Если t равно nil, clear не выполняет никаких действий.

func close

func close(c chan<- Type)

Встроенная функция close закрывает канал, который должен быть либо двунаправленным, либо только для отправки. Она должна выполняться только отправителем, никогда не получателем, и приводит к закрытию канала после получения последнего отправленного значения. После получения последнего значения из закрытого канала c любое получение из c будет выполняться без блокировки, возвращая нулевое значение для элемента канала. Форма

x, ok := <-c

также установит ok в false для закрытого и пустого канала.

func complex

func complex(r, i FloatType) ComplexType

Встроенная функция complex создает комплексное значение из двух значений с плавающей запятой. Действительная и мнимая части должны быть одинакового размера, либо float32, либо float64 (или приравниваемы к ним), и возвращаемое значение будет соответствующим комплексным типом (complex64 для float32, complex128 для float64).

func copy

func copy(dst, src []Type) int

Встроенная функция copy копирует элементы из исходного слайса в целевой слайс. (В качестве особого случая она также копирует байты из строки в слайс байтов.) Исходный и целевой слайсы могут пересекаться. Copy возвращает количество скопированных элементов, которое будет минимальным из len(src) и len(dst).

func delete

func delete(m map[Type]Type1, key Type)

Встроенная функция delete удаляет элемент с указанным ключом (m[key]) из карты. Если m равно nil или такого элемента нет, delete не выполняет никаких действий.

func imag

func imag(c ComplexType) FloatType

Встроенная функция imag возвращает мнимую часть комплексного числа c. Возвращаемое значение будет иметь тип с плавающей запятой, соответствующий типу c.

func len

func len(v Type) int

Встроенная функция len возвращает длину v в соответствии с его типом:

  • Массив: количество элементов в v.
  • Указатель на массив: количество элементов в *v (даже если v равен nil).
  • Срез или карта: количество элементов в v; если v равен nil, len(v) равен нулю.
  • Строка: количество байтов в v.
  • Канал: количество элементов в очереди (непрочитанных) в буфере канала; если v равно nil, len(v) равно нулю.

Для некоторых аргументов, таких как строковый литерал или простое массивное выражение, результатом может быть константа. Подробности см. в разделе «Длина и емкость» спецификации языка Go.

func make

func make(t Type, size ...IntegerType) Type

Встроенная функция make выделяет и инициализирует объект типа slice, map или chan (только). Как и в случае с new, первый аргумент является типом, а не значением. В отличие от new, тип возвращаемого значения make совпадает с типом его аргумента, а не является указателем на него. Спецификация результата зависит от типа:

  • Срез: размер определяет длину. Емкость среза равна его длине. Можно указать второй целочисленный аргумент, чтобы задать другую емкость; она не должна быть меньше длины. Например, make([]int, 0, 10) выделяет базовый массив размером 10 и возвращает срез длиной 0 и емкостью 10, который поддерживается этим базовым массивом.
  • Карта: выделяется пустая карта с достаточным пространством для хранения указанного количества элементов. Размер может быть опущен, в этом случае выделяется небольшой начальный размер.
  • Канал: буфер канала инициализируется с указанной емкостью буфера. Если размер равен нулю или опущен, канал не имеет буфера.

func max

func max[T cmp.Ordered](x T, y ...T) T

Встроенная функция max возвращает наибольшее значение из фиксированного числа аргументов типов cmp.Ordered. Должно быть как минимум один аргумент. Если T является типом с плавающей запятой и любой из аргументов является NaN, max вернет NaN.

func min

func min[T cmp.Ordered](x T, y ...T) T

Встроенная функция min возвращает наименьшее значение из фиксированного числа аргументов типов cmp.Ordered. Должно быть как минимум один аргумент. Если T является типом с плавающей запятой и любой из аргументов является NaN, min вернет NaN.

func new

func new(Type) *Type

Встроенная функция new выделяет память. Первый аргумент — это тип, а не значение, и возвращаемое значение — это указатель на вновь выделенное нулевое значение этого типа.

func panic

func panic(v any)

Встроенная функция panic останавливает нормальное выполнение текущего goroutine.

Когда функция F вызывает panic, нормальное выполнение F немедленно останавливается. Все функции, выполнение которых было отложено F, выполняются обычным образом, а затем F возвращается к своему вызывающему. Для вызывающего G вызов F ведет себя как вызов panic, прекращая выполнение G и запуская все отложенные функции. Это продолжается до тех пор, пока все функции в выполняющемся goroutine не остановятся в обратном порядке. В этот момент программа завершается с ненулевым кодом выхода. Эта последовательность завершения называется паникой и может контролироваться встроенной функцией recover.

Начиная с Go 1.21, вызов panic с нулевым значением интерфейса или нетипизированным nil вызывает ошибку выполнения (другой вид паники). Настройка GODEBUG panicnil=1 отключает ошибку выполнения.

func print

func print(args ...Type)

Встроенная функция print форматирует свои аргументы способом, специфичным для реализации, и записывает результат в стандартный поток ошибок. Print полезна для начальной загрузки и отладки; ее сохранение в языке не гарантируется.

func println

func println(args ...Type)

Встроенная функция println форматирует свои аргументы способом, специфичным для реализации, и записывает результат в стандартный поток ошибок. Между аргументами всегда добавляются пробелы и добавляется новая строка. Println полезна для начальной настройки и отладки; ее сохранение в языке не гарантируется.

func real

func real(c ComplexType) FloatType

Встроенная функция real возвращает действительную часть комплексного числа c. Возвращаемое значение будет иметь тип с плавающей запятой, соответствующий типу c.

func recover

func recover() any

Встроенная функция recover позволяет программе управлять поведением goroutine, входящего в состояние паники.

Вызов recover внутри отложенной функции (но не в любой функции, вызываемой ею) останавливает последовательность паники, восстанавливая нормальное выполнение и извлекая значение ошибки, переданное вызову panic.

Если recover вызывается вне отложенной функции, он не останавливает последовательность паники. В этом случае, или когда goroutine не входит в состояние паники, recover возвращает nil.

До Go 1.21 recover также возвращала nil, если panic вызывалась с аргументом nil. Подробности см. в разделе [panic].

Пример

Функция recover() используется для перехвата паники (panic) и восстановления нормального выполнения программы. Вот несколько практических примеров:

Пример 1: Базовое использование recover

package main

import "fmt"

func main() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered from panic:", r)
        }
    }()

    fmt.Println("Start")
    panic("something went wrong")
    fmt.Println("This won't be executed")
}

Вывод:

$$Start Recovered from panic: something went wrong$$

Пример 2: Восстановление после деления на ноль

package main

import "fmt"

func safeDivide(a, b int) (result int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Recovered:", r)
            result = 0 // устанавливаем значение по умолчанию
        }
    }()
    
    return a / b // может вызвать панику при b = 0
}

func main() {
    fmt.Println(safeDivide(10, 2)) // 5
    fmt.Println(safeDivide(10, 0)) // 0 (после восстановления)
    fmt.Println("Program continues")
}

Пример 3: Разные типы паники

package main

import "fmt"

func handlePanic() {
    if r := recover(); r != nil {
        switch v := r.(type) {
        case string:
            fmt.Println("String panic:", v)
        case error:
            fmt.Println("Error panic:", v)
        default:
            fmt.Printf("Unknown panic: %v (%T)\n", v, v)
        }
    }
}

func main() {
    defer handlePanic()
    
    // Можно раскомментировать любой вариант:
    panic("string panic")
    // panic(fmt.Errorf("error panic"))
    // panic(42)
}

Пример 4: recover в горутинах

package main

import (
    "fmt"
    "time"
)

func worker(id int) {
    defer func() {
        if r := recover(); r != nil {
            fmt.Printf("Worker %d recovered: %v\n", id, r)
        }
    }()
    
    if id == 2 {
        panic(fmt.Sprintf("panic in worker %d", id))
    }
    fmt.Printf("Worker %d working\n", id)
}

func main() {
    for i := 1; i <= 3; i++ {
        go worker(i)
    }
    time.Sleep(time.Second) // Даем время горутинам завершиться
}

Пример 5: Вложенные recover

package main

import "fmt"

func inner() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Inner recovered:", r)
        }
    }()
    panic("inner panic")
}

func outer() {
    defer func() {
        if r := recover(); r != nil {
            fmt.Println("Outer recovered:", r)
        }
    }()
    inner()
    fmt.Println("This won't be executed")
}

func main() {
    outer()
    fmt.Println("Program continues")
}

Важные замечания:

  1. recover() работает только внутри defer-функций
  2. Каждый вызов recover() обрабатывает только одну панику
  3. После восстановления выполнение продолжается после блока defer
  4. В Go 1.21+ recover() возвращает nil только если паники не было
  5. Не злоупотребляйте recover - используйте только для действительно неожиданных ошибок