Функция unsafe.Add

Функция unsafe.Add выполняет арифметику указателей, позволяя безопасно прибавлять целочисленное смещение к указателю типа unsafe.Pointer. Она принимает два параметра: первый параметр - указатель типа unsafe.Pointer, второй параметр - смещение в байтах типа uintptr. Функция возвращает новый указатель типа unsafe.Pointer, смещенный на указанное количество байт.

Синтаксис

gounsafe.Add(ptr, offset)

Пример

Давайте прибавим смещение к указателю на первый элемент слайса, чтобы получить указатель на второй элемент:

gopackage main

import (
  "fmt"
  "unsafe"
)

func main() {
  nums := []int{1, 2, 3, 4, 5}
  ptr := unsafe.Pointer(&nums[0])
  secondPtr := unsafe.Add(ptr, unsafe.Sizeof(nums[0]))
  second := (*int)(secondPtr)
  fmt.Println(*second)
}

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

go2

Пример

Давайте используем unsafe.Add для доступа к полю структуры по смещению, используя функцию unsafe.Offsetof:

gopackage main

import (
  "fmt"
  "unsafe"
)

type Person struct {
  Age   int
  Name  string
}

func main() {
  p := Person{Age: 30, Name: "John"}
  ptr := unsafe.Pointer(&p)
  namePtr := unsafe.Add(ptr, unsafe.Offsetof(p.Name))
  name := (*string)(namePtr)
  fmt.Println(*name)
}

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

go"John"

Пример

Давайте используем unsafe.Add для итерации по элементам слайса с помощью арифметики указателей:

gopackage main

import (
  "fmt"
  "unsafe"
)

func main() {
  nums := []int{1, 2, 3, 4, 5}
  size := unsafe.Sizeof(nums[0])
  ptr := unsafe.Pointer(&nums[0])

  for i := 0; i < len(nums); i++ {
    current := unsafe.Add(ptr, uintptr(i)*size)
    fmt.Print(*(*int)(current), " ")
  }
}

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

go"1 2 3 4 5 "

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

  • функцию unsafe.Pointer,
    которая используется для преобразования указателей и безопасной работы с памятью
  • функцию unsafe.Sizeof,
    которая возвращает размер типа в байтах
  • функцию unsafe.Offsetof,
    которая возвращает смещение поля структуры от начала структуры
  • функцию unsafe.Slice,
    которая создает слайс из указателя на массив и длины