首页 > 其他分享 >Golang标准库:非类型安全操作(Arbitrary 类型 Pointer 类型 Sizeof 函数 Offsetof 函数)

Golang标准库:非类型安全操作(Arbitrary 类型 Pointer 类型 Sizeof 函数 Offsetof 函数)

时间:2023-12-07 10:04:21浏览次数:42  
标签:函数 fmt unsafe Golang Println 内存 类型 Pointer


unsafe库徘徊在“类型安全”边缘,由于它们绕过了 Golang 的内存安全原则,一般被认为使用该库是不安全的。但是,在许多情况下,unsafe库的作用又是不可替代的,灵活地使用它们可以实现对内存的直接读写操作。在reflect库、syscall库以及其他许多需要操作内存的开源项目中都有对它的引用。

unsafe库源码极少,只有两个类型的定义和三个方法的声明。

Arbitrary 类型

官方导出这个类型只是出于完善文档的考虑,在其他的库和任何项目中都没有使用价值,除非程序员故意使用它。

Pointer 类型

这个类型比较重要,它是实现定位欲读写的内存的基础。官方文档对该类型有四个重要描述:

  • (1)任何类型的指针都可以被转化为 Pointer
  • (2)Pointer 可以被转化为任何类型的指针
  • (3)uintptr 可以被转化为 Pointer
  • (4)Pointer 可以被转化为 uintptr

举例来说,该类型可以这样使用:

func main() {
        i := 100
        fmt.Println(i)  // 100
        p := (*int)unsafe.Pointer(&i)
        fmt.Println(*p) // 100
        *p = 0
        fmt.Println(i)  // 0
        fmt.Println(*p) // 0
    }

Sizeof 函数

该函数的定义如下:

func Sizeof(v ArbitraryType) uintptr

Sizeof 函数返回变量 v 占用的内存空间的字节数,该字节数不是按照变量 v 实际占用的内存计算,而是按照 v 的“ top level ”内存计算。比如,在 64 位系统中,如果变量 v 是 int 类型,会返回 16,因为 v 的“ top level ”内存就是它的值使用的内存;如果变量 v 是 string 类型,会返回 16,因为 v 的“ top level ”内存不是存放着实际的字符串,而是该字符串的地址;如果变量 v 是 slice 类型,会返回 24,这是因为 slice 的描述符就占了 24 个字节。

Offsetof 函数

该函数的定义如下:

func Offsetof(v ArbitraryType) uintptr

该函数返回由 v 所指示的某结构体中的字段在该结构体中的位置偏移字节数,注意,v 的表达方式必须是“ struct.filed ”形式。
举例说明,在 64 为系统中运行以下代码:

type Datas struct{
        c0 byte
        c1 int
        c2 string
        c3 int
    }
    func main(){
        var d Datas
        fmt.Println(unsafe.Offset(d.c0))    // 0
        fmt.Println(unsafe.Offset(d.c1))    // 8
        fmt.Println(unsafe.Offset(d.c2))    // 16
        fmt.Println(unsafe.Offset(d.c3))    // 32
    }

如果知道的结构体的起始地址和字段的偏移值,就可以直接读写内存:

d.c3 = 13
    p := unsafe.Pointer(&d)
	offset := unsafe.Offsetof(d.c3)
	q := (*int)(unsafe.Pointer(uintptr(p) + offset))
    fmt.Println(*q) // 13
    *p = 1013
    fmt.Println(d.c3)   // 1013

link:https://github.com/polaris1119/The-Golang-Standard-Library-by-Example/


标签:函数,fmt,unsafe,Golang,Println,内存,类型,Pointer
From: https://blog.51cto.com/zhangxueliang/8718179

相关文章

  • 租用服务器带宽类型应用
    服务器带宽类型多样,以满足不同行业的需求。本文将介绍香港常见的服务器带宽类型及其应用领域。1.共享带宽共享带宽是指多个用户共同使用同一台服务器的带宽资源。这种带宽类型适用于小型企业或个人网站,因为其成本较低。由于多个用户共享带宽资源,因此在高峰期可能会出现网络拥塞和......
  • CMC-ORACLE-函數row_number() over(partition by )函数用法
    row_number()over(partitionby)函数用法row_number()over(partitionby),作为oracle常用的分析函数,身为数据开发时必须要掌握的。不过一段时间不用,难免会有些忘记,今天整理一下一些场景下的用法。现有表(test_rownumber)有如下数据:RUSER(用户名)RID(用户编号)RSAL(用户消费)RD......
  • 无涯教程-Erlang - memory函数
    返回一个列表,其中包含有关由Erlang动态分配的内存的信息,该列表的每个元素都是一个元组{Type,Size},第一个元素Type是描述内存类型的原子。memory-语法memory()memory-返回值返回一个列表,其中包含有关由Erlang仿真器动态分配的内存的信息。-module(helloLearnfk).-export......
  • STM32学习笔记_点灯(基于库函数方式)
    1.使能外设时钟输入:RCC_APB2PeriphClockCmd函数,查看函数定义,根据函数定义填写参数:RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);2.配置端口模式输入函数GPIO_Init,跳转到函数定义,查看函数定义得知函数体的第二个参数是结构体,先定义结构体并且填写结构体的各个参数,然后填写......
  • 函数(1)基本概念,参数,调用,声明和定义
    一、C语言中函数分为库函数和自定义函数库函数:C语言本身提供的函数,有函数名、返回值类型和函数参数常用的库函数有IO函数(stdio.h),字符串操作函数(strlen),字符操作函数(大小写),内存操作函数(memset),时间/日期函数(time),数学函数(sqrt)以及其他库函数。intmain(){ chararr1[]=......
  • SQL ALTER TABLE 语句- 灵活修改表结构和数据类型
    SQLALTERTABLE语句SQLALTERTABLE语句用于在现有表中添加、删除或修改列,也可用于添加和删除各种约束。ALTERTABLE-添加列要在表中添加列,请使用以下语法:ALTERTABLE表名ADD列名数据类型;以下SQL向"Customers"表添加了一个"Email"列:ALTERTABLECustomersA......
  • 无涯教程-Erlang - element函数
    该方法返回元组中的第Nth元素。element-语法element(N,Tuple)N    -元组中需要返回的位置。Tuple -需要为其返回第N元素的元组。element-返回值该方法返回元组中的第Nth元素。-module(helloLearnfk).-export([start/0]).start()->io:......
  • C++中的函数重载(C++Primer)
    一、什么是函数的重载在同一作用域下,几个函数的函数名相同,但其内部的形参列表不同,我们称之为函数的重载,这里的不同不仅仅指形参数量的不同,还包括形参类型的不同。voidprint(constchar*const_p);voidprint(constchar*begin,constchar*end);voidprint(constint*const_p)......
  • SQL ALTER TABLE 语句- 灵活修改表结构和数据类型
    SQLALTERTABLE语句SQLALTERTABLE语句用于在现有表中添加、删除或修改列,也可用于添加和删除各种约束。ALTERTABLE-添加列要在表中添加列,请使用以下语法:ALTERTABLE表名ADD列名数据类型;以下SQL向"Customers"表添加了一个"Email"列:ALTERTABLECustomers......
  • 开发者的福音:TinyVue 组件库文档大优化!类型更详细,描述更清晰!
    你好,我是Kagol。前言从今年2月份开源以来,有不少朋友给我们TinyVue组件库提了文档优化的建议,这些建议都非常中肯,我们也在持续对文档进行优化,并且从中总结出了大家对于文档优化的一些共性问题,形成了一份《组件demo和api文档编写规范》为了提升开发者阅读文档的体验,从9月......