Тип unsafe.Pointer

Тип unsafe.Pointer позволяет представлять указатель на любое значение в памяти. Он используется для низкоуровневых операций, когда необходимо обойти строгую типизацию Go. Первый параметр - это указатель на любое значение, а результат - указатель типа unsafe.Pointer.

Важно понимать, что использование unsafe.Pointer требует особой осторожности, так как неправильное использование может привести к неопределенному поведению и панике программы. Этот тип следует использовать только в тех случаях, когда без него невозможно обойтись.

Синтаксис

gounsafe.Pointer(&value)

Пример работы с преобразованием типов

Давайте рассмотрим, как можно преобразовать указатель на один тип в указатель на другой тип:

gopackage main

import (
  "fmt"
  "unsafe"
)

func main() {
  var i int32 = 42
  var f float32

  // Преобразование *int32 в *float32 через unsafe.Pointer
  f = *(*float32)(unsafe.Pointer(&i))
  fmt.Println(f)
}

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

go"5.885453e-44"

Пример работы с памятью структур

Покажем, как можно получить доступ к полям структуры в обход безопасных методов:

gopackage main

import (
  "fmt"
  "unsafe"
)

type User struct {
  Name string
  Age  int
}

func main() {
  user := User{Name: "John", Age: 30}
  ptr := unsafe.Pointer(&user)

  // Получаем указатель на поле Age
  agePtr := (*int)(unsafe.Pointer(uintptr(ptr) + unsafe.Offsetof(user.Age)))
  *agePtr = 31

  fmt.Printf("%+v", user)
}

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

go{Name:John Age:31}

Пример использования с функциями из пакета unsafe

Рассмотрим работу с функциями unsafe.Sizeof и unsafe.Alignof, которые часто используются вместе с unsafe.Pointer:

gopackage main

import (
  "fmt"
  "unsafe"
)

type Data struct {
  A byte
  B int64
  C bool
}

func main() {
  var d Data
  ptr := unsafe.Pointer(&d)

  fmt.Printf("Size of Data: %d", unsafe.Sizeof(d))
  fmt.Printf("Alignment of Data: %d", unsafe.Alignof(d))
  fmt.Printf("Offset of B: %d", unsafe.Offsetof(d.B))
}

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

go"Size of Data: 24"
"Alignment of Data: 8"
"Offset of B: 8"

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

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