Функция runtime.Caller

Функция runtime.Caller позволяет получить информацию о вызывающем коде. Она возвращает номер программного счетчика, имя файла и номер строки, где произошел вызов этой функции. Параметр skip указывает, сколько уровней стека нужно пропустить вверх по цепочке вызовов: значение 0 возвращает информацию о самой функции runtime.Caller, 1 - о ее вызывающем, и так далее.

Синтаксис

gopc, file, line, ok := runtime.Caller(skip int)

Пример

Давайте получим информацию о текущем вызове функции runtime.Caller:

gopackage main

import (
  "fmt"
  "runtime"
)

func main() {
  pc, file, line, ok := runtime.Caller(0)
  if ok {
    fmt.Printf("pc: %v, file: %s, line: %d", pc, file, line)
  }
}

Результат выполнения кода:

go"pc: 17478419, file: /path/to/main.go, line: 10"

Пример

Давайте создадим вспомогательную функцию для логирования, которая будет показывать место вызова:

gopackage main

import (
  "fmt"
  "runtime"
)

func logMessage(msg string) {
  pc, file, line, ok := runtime.Caller(1)
  if ok {
    fmt.Printf("[%s:%d] %s", file, line, msg)
  }
}

func main() {
  logMessage("Hello, World!")
}

Результат выполнения кода:

go"[/path/to/main.go:15] Hello, World!"

Пример

Давайте используем функцию для получения информации о вызывающем коде через несколько уровней вложенности:

gopackage main

import (
  "fmt"
  "runtime"
)

func level3() {
  pc, file, line, ok := runtime.Caller(2)
  if ok {
    fmt.Printf("Caller from level3: %s:%d", file, line)
  }
}

func level2() {
  level3()
}

func level1() {
  level2()
}

func main() {
  level1()
}

Результат выполнения кода:

go"Caller from level3: /path/to/main.go:22"

Смотрите также

  • функцию runtime.Callers,
    которая заполняет срез адресами программных счетчиков вызывающих функций
  • функцию runtime.FuncForPC,
    которая возвращает информацию о функции по адресу программного счетчика
  • функцию runtime.Stack,
    которая возвращает текущий стек вызовов в виде среза байтов
  • тип runtime.Frame,
    который представляет один фрейм в стеке вызовов