Пакет unsafe в Golang используется для низкоуровневых операций во время выполнения. Эти операции, как правило, небезопасны, потому что они могут нарушить безопасность типов и памяти Golang, а программы, использующие небезопасные пакеты, могут повлиять на переносимость и совместимость. Затем посмотрите на типы и функции в небезопасном пакете.
небезопасно Тип указателя
Обычно используется для преобразования типов и арифметики указателей, определяемой следующим образом:
type Pointer *ArbitraryType
Указатели других типов могут быть преобразованы в тип unsafe.Pointer для низкоуровневых манипуляций. Посмотрите на простой пример:
package main
import (
"fmt"
"unsafe"
)
func main() {
i := 30
ptr1 := &i
var ptr2 *int64 = (*int64)(unsafe.Pointer(ptr1))
*ptr2 = 8
fmt.Println(i)
}
небезопасный тип ArbitraryType
Он определяется следующим образом:
type ArbitraryType int
ArbitraryType используется только в целях документации и на самом деле не является частью пакета unsafe для представления типа произвольного выражения Go.
небезопасный тип.IntegerType
Он определяется следующим образом:
type IntegerType int
IntegerType используется только в целях документации и на самом деле не является частью небезопасного пакета для представления произвольных целочисленных типов.
небезопасно. Добавить функцию
Он определяется следующим образом:
func Add(ptr Pointer, len IntegerType) Pointer
Он используется для операции добавления указателя, добавления указателя и указанного смещения для получения нового указателя. Простой пример выглядит следующим образом:
package main
import (
"fmt"
"unsafe"
)
func main() {
arr := []int{1, 2, 3, 4}
index := 2
ptr := unsafe.Pointer(&arr[0])
newPtr := unsafe.Add(ptr, uintptr(index)*unsafe.Sizeof(arr[0]))
cc := (*int)(newPtr)
fmt.Println(*cc)
fmt.Println(newPtr)
}
небезопасно.
Он определяется следующим образом:
func Sizeof(x ArbitraryType) uintptr
Используется для получения размера в байтах типа или значения. Простой пример выглядит следующим образом:
package main
import (
"fmt"
"unsafe"
)
func main() {
var arr [5]int
fmt.Println(unsafe.Sizeof(arr)) // 输出: 40
fmt.Println(unsafe.Sizeof(0)) // 输出: 8
}
функция unsafe.Slice
Он определяется следующим образом:
func Slice(ptr *ArbitraryType, len IntegerType) []ArbitraryType
Используется для создания среза, который совместно использует базовые данные с исходным массивом. Простой пример выглядит следующим образом:
package main
import (
"fmt"
"unsafe"
)
func main() {
var arr [5]int
arr[0] = 10
arr[1] = 20
arr[2] = 30
arr[3] = 40
arr[4] = 50
slice := unsafe.Slice(&arr[0], 3)
fmt.Println(slice) // 输出: [10 20 30]
}
Определите массив arr, содержащий 5 целых чисел, а затем используйте функцию unsafe.Slice для создания среза среза, начиная с индекса 0 и имеющего длину 3.
небезопасно.Offsetof
Он определяется следующим образом:
func Offsetof(x ArbitraryType) uintptr
Функция состоит в том, чтобы вернуть количество байтов от позиции члена структуры в памяти до начала структуры (смещение первого поля структуры равно 0). Простой пример выглядит следующим образом:
package main
import (
"fmt"
"unsafe"
)
type MyStruct struct {
Field1 int64
Field2 string
}
func main() {
var myStruct MyStruct
fmt.Println(unsafe.Offsetof(myStruct.Field1)) // 输出: 0
fmt.Println(unsafe.Offsetof(myStruct.Field2)) // 输出: 8
}
небезопасно.Alignof
Он определяется следующим образом:
func Alignof(x ArbitraryType) uintptr
Возвращает количество байтов, необходимых для выравнивания аргумента. Для некоторых структур выравнивание их полей в памяти может повлиять на размер памяти, занимаемой структурой. Простой пример выглядит следующим образом:
package main
import (
"fmt"
"unsafe"
)
type MyStruct struct {
Field1 int
Field2 string
}
func main() {
fmt.Println(unsafe.Alignof(int(0))) // 输出: 8
fmt.Println(unsafe.Alignof(string(""))) // 输出: 8
fmt.Println(unsafe.Alignof(MyStruct{})) // 输出: 8
}
краткое содержание
Пакет unsafe предоставляет некоторые низкоуровневые операции. Вы должны быть осторожны при их использовании. Вы должны хорошо знать, что вы делаете, чтобы избежать создания небезопасных проблем.