指针

Z1h 语言中指针是很容易学习的, Z1h 语言中使用指针可以更简单的执行一些任务. 接下来让我们了解一下 Z1h 语言内指针的概念. 一个指针变量指向了一个值的内存地址. 如果你有使用C、C++、Go等语言的经验, 那么就很容易理解Z1h的指针 Z1h 语言的取地址符是 &, 放到一个变量前使用就会返回相应变量的内存地址. 以下实例演示了变量在内存中地址 num = 10 print(fmt.Sprintf("指针地址: %x", &num)) // 指针地址: c0004d3b70 输出的结果中, "c0004d3b70"不是固定的, 取决于系统分配的内存地位 现在我们已经了解了什么是内存地址和如何去访问它. 接下来我们将具体介绍指针

声明

指针的声明, 需要对一个变量或者字面值&进行内存取址, 如: num = 1 numPtr = &num numPtr = &1 其和值最大的区别之一在于, 指向相同内存的指针, 其值是同时变化的 a = 1; b = a; a = 2; print(b); // 仍然是1 a = &1; b = a; *a = 2; print(b); // 变成了2

取值

可以使用*符号获取指针的内容值 a = 1 b = &a print(type(a), type(b), type(*b)) printf("%v = %v", b, *b) 请注意, 由于指针的操作符 * 和乘号相同, 所以在自动插入换行符的逻辑上有一些二义性, 所以强烈建议在使用指针取值符时, 上一个语句以显式的 ; 结尾

指针的妙用

(Go)读取struct的内置隐藏对象

根据标准type sync.Map struct的定义, 在内存区域最前面的是sync.Mutex结构, 可以通过以下方式获取, 并且自主操作加锁: m = new(sync.Map) lock = new(sync.Mutex, m + 0) // m+0可以将指针 m.a = 123 print('Keys:', Object.keys(m)) lock.Lock() go func() { sleep(3) lock.Unlock() }() st = now() m.b = 222; // 阻塞等待Unlock 'Cost: %+v, Keys: %v'.fmt(time.Since(st), Object.keys(m))

数组指针

数组 "长度不可变"的特性不同, 数组指针包含了可以使数组长度变化的各种方法, 详见 数组

字符串指针

字符串指针由16个byte组成, 前8个byte是字符串在堆内存的位置, 后8个byte是长度 通过修改指针来达成截断的目的 str = &"abcdefg" print(`Before ${str}, len = ${len(*str)}`) range(16).map(e=>print(`Offset=${e}, Value=${str+e}`)); *(str + 8) = byte(3) // 可以试着设为更大的值, 看看会发生什么 print(`After ${str}, len = ${len(*str)}`) 如果你想要访问堆内存来直接修改字符串的内容, 也是可以的 str = &"abcdefg" i = *cast(str, '*i'); // 将其堆内存的8byte提出来, 并取值转成int类型 *cast(i, '*b') = byte('z') // 修改堆内存的值, 将第一个byte改成'z' print(str) // "zbcdefg" 更多用法待更新…